<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
	<meta charset="utf-8">
	<meta name="theme-color" content="#222222">
	<meta content="yes" name="apple-mobile-web-app-capable">
	<link rel="shortcut icon" href=""/>
	<title>WLED</title>
	<script>function feedback(){}</script>
<style>
@font-face {
	font-family: "WIcons";
	src: url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff');
}

:root {
	--c-1: #111;
	--c-f: #fff;
	--c-2: #222;
	--c-3: #333;
	--c-4: #444;
	--c-5: #555;
	--c-6: #666;
	--c-8: #888;
	--c-b: #bbb;
	--c-c: #ccc;
	--c-e: #eee;
	--c-d: #ddd;
	--c-r: #831;
	--t-b: 0.5;
	--c-o: rgba(34, 34, 34, 0.9);
	--c-tb : rgba(34, 34, 34, var(--t-b));
	--c-tba: rgba(102, 102, 102, var(--t-b));
	--c-tbh: rgba(51, 51, 51, var(--t-b));
	/*following are internal*/
	--th: 70px;
	--tp: 70px;
	--bh: 63px;
	--tbp: 14px 14px 10px 14px;
	--bbp: 9px 0 7px 0;
	--bhd: none;
	--bmt: 0px;
}

html {
	touch-action: manipulation;
}

body {
	margin: 0;
	background-color: var(--c-1);
	font-family: Helvetica, Verdana, sans-serif;
	font-size: 17px;
	color: var(--c-f);
	text-align: center;
	-webkit-touch-callout: none;
		-webkit-user-select: none;
			 -moz-user-select: none;
				-ms-user-select: none;
						user-select: none;
	-webkit-tap-highlight-color: transparent;
  scrollbar-width: 6px;
  scrollbar-color: var(--c-sb) transparent;
}

html,
body {
	height: 100%;
	width: 100%;
	position: fixed;
	overscroll-behavior: none;
}

#bg {
	height: 100vh;
	width: 100vw;
	position: fixed;
	z-index: -10;
	background-position: center;
	background-repeat: no-repeat;
	background-size: cover;
	opacity: 0;
	transition: opacity 2s;
}

p {
	margin: 10px 0 2px 0;
	color: var(--c-d);
}

button {
	outline: none;
	cursor: pointer;
}

.labels {
	margin: 0;
	padding: 8px 0 2px 0;
}

#namelabel {
	position: fixed;
	bottom: calc(var(--bh) + 5px);
	right: 4px;
	color: var(--c-6);
	writing-mode: vertical-rl;
}

.bri {
	padding: 4px;
}

.wrapper {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	background: var(--c-tb);
	z-index: 1;
}

.icons {
	font-family: 'WIcons';
	font-style: normal;
	font-size: 24px;
	line-height: 1;
	display: inline-block;
	margin: -2px 0 4px 0;
}

.huge {
	font-size: 42px;
}

.infot {
	table-layout: fixed;
	width: 100%;
}

.segt {
	table-layout: fixed;
	width: 76%;
}

.segtd {
	text-align: center;
	text-transform: uppercase;
	font-size: 14px;
}

.keytd {
	text-align: left;
	padding-bottom: 8px;
}

.valtd {
	text-align: right;
	padding-bottom: 8px;
}

.slider-icon
{
	transform: translate(6px,3px);
	color: var(--c-d);
}

.e-icon
{
	transform: translateY(3px);
	color: var(--c-d);
}

.sel-icon {
	transform: translateX(3px);
	color: var(--c-d);
}

.flr {
	float: right;
	cursor: pointer;
	margin: 0;
	color: var(--c-f);
	transform: rotate(0deg);
	transition: transform 0.3s;
}

.exp {
	transform: rotate(180deg);
}

.il {
	display: inline-block;
	vertical-align: middle;
}

#liveview {
	height: 4px;
	display: none;
	width: 100%;
	border: 0px;
}

.tab {
	background-color: transparent;
	color: var(--c-d);
}

.bot {
	position: fixed;
	bottom: 0;
	left: 0;
	width: 100%;
	background-color: var(--c-tb);
}

.tab button {
	background-color: transparent;
	float: left;
	border: none;
	transition: color 0.3s, background-color 0.3s;
	font-size: 17px;
	color: var(--c-c);
}

.top button {
	padding: var(--tbp);
}											 

.bot button {
	padding: var(--bbp);
	width:25%;
}

.tab button:hover {
	background-color: var(--c-tbh);
	color: var(--c-e);
}

.tab button.active {
	background-color: var(--c-tba) !important;
	color: var(--c-f);
}

.active {
	background-color: var(--c-6) !important;
	color: var(--c-f);
}

.container {
	--n: 1;
	width: 100%;
	width: calc(var(--n)*100%);
	height: calc(100% - var(--tp) - var(--bh));
	margin-top: var(--tp);
	transform: translate(calc(var(--i, 0)/var(--n)*-100%));
	overscroll-behavior: none;
}

.tabcontent {
	float: left;
	position: relative;
	width: 100%;
	width: calc(100%/var(--n));
	padding: 11px 0;
	box-sizing: border-box;
	border: 0px;
	overflow: auto;
	height: 100%;
	overscroll-behavior: none;
}

#Effects {
	padding-top: 0;
	margin-top: 11px;
	height: calc(100% - 11px);
}

.smooth { transition: transform	calc(var(--f, 1)*.5s) ease-out }

.tab-label {
	margin: 0 0 -5px 0;
	padding-bottom: 4px;
}

.overlay {
	position: fixed;
	height: 100%;
	width: 100%;
	top: 0;
	left: 0;
	background-color: var(--c-3);
	font-size: 24px;
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 11;
	opacity: 0.95;
	transition: 0.7s;
	pointer-events: none;
}

.staytop {
	display: block;
	position: -webkit-sticky;
	position: sticky;
	background: var(--c-1);
	top: -1px;
	z-index: 1;
	margin-top: 1px;
	width: 274px;
	margin: auto;
	border-radius: 25px;
}

#staytop1 {
	top: 28px;
}

#staytop2 {
	top: 56px;
}

#fxb0 {
	margin-bottom: 2px;
  filter: drop-shadow(0 0 1px #000);
}

.first {
	margin-top: 18px !important;
}

#toast {
	opacity: 0;
	background-color: var(--c-5);
	max-width: 90%;
	color: var(--c-f);
	text-align: center;
	border-radius: 5px;
	padding: 16px;
	position: fixed;
	z-index: 5;
	left: 50%;
	transform: translateX(-50%);
	bottom: calc(var(--bh) + 22px);
	font-size: 17px;
	pointer-events: none;
}

#toast.show {
	opacity: 1;
	animation: fadein 0.5s, fadein 0.5s 2.5s reverse;
}

#toast.error {
	opacity: 1;
	background-color: #b21;
	animation: fadein 0.5s;
}

.modal {
	position:fixed;
	left: 0px;
	bottom: 0px;
	right: 0px;
	top: calc(var(--th) - 1px);
	background-color: var(--c-o);
	transform: translateY(100%);
	transition: transform 0.4s;
	padding: 8px;
	font-size: 20px;
	overflow: auto;
}

#info {
	z-index: 3;
}

#rover {
	z-index: 2;
}

#roverstar {
	position: fixed;
	top: calc(var(--th) + 5px);
	left: 1px;
	display: none;
	cursor: pointer;
}

#connind {
	position: fixed;
	bottom: calc(var(--bh) + 5px);
	left: 4px;
	padding: 5px;
	border-radius: 5px;
	background-color: #a90;
	z-index: -2;
}

#imgw {
	width: 200px;
	height: 55px;
	display: inline-block;
}

#kv {
	max-width: 490px;
	display: inline-block;
}

#lv {
	max-width: 600px;
	display: inline-block;
}

#heart {
	transition: color 0.9s;
	font-size: 16px;
	color: #f00;
}

img {
	max-width: 100%;
	max-height: 100%;
}

@keyframes fadein {
	from {bottom: 0; opacity: 0;}
	to {bottom: calc(var(--bh) + 22px); opacity: 1;}
}

.sliderdisplay {
	content:'';
	position: absolute;
	top: 13px; bottom: 13px;
	left: 10px; right: 10px;
	background: var(--c-4);
	border-radius: 17px;
	pointer-events: none;
	z-index: -1;
}

.sliderbubble {
    width: 36px;
    line-height: 24px;
    background: var(--c-3);
    position: absolute;
    transform: translateX(-50%);
    border-radius: 12px;
    margin-left: 12px;
    margin-top: 3px;
    padding: 0px;
    display: inline;
}

.hidden {
	display: none;
}

input[type=range] {
	-webkit-appearance: none;
	width: 220px;
	padding: 0px;
	margin: 0px 10px 0px 10px;
	background-color: transparent;
	cursor: pointer;
}
input[type=range]:focus {
	outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
	width: 100%;
	height: 30px;
	cursor: pointer;
	background: transparent;
}
input[type=range]::-webkit-slider-thumb {
	height: 16px;
	width: 16px;
	border-radius: 17px;
	background: var(--c-f);
	cursor: pointer;
	-webkit-appearance: none;
	margin-top: 7px;
}
input[type=range]::-moz-range-track {
	width: 100%;
	height: 30px;
	background-color: rgba(0, 0, 0, 0);
}
input[type=range]::-moz-range-thumb {
	border: 0px solid rgba(0, 0, 0, 0);
	height: 16px;
	width: 16px;
	border-radius: 17px;
	background: var(--c-f);
	transform: translateY(7px);
}
input[type=range]:active + .sliderbubble {
	display: inline;
	transform: translateX(-50%);
}

#wwrap {
	display: none;
}

.sliderwrap {
	height: 30px;
	width: 240px;
	position: relative;
}

.sws {
	width: 212px;
}

.sis {
	width: 192px !important;
}

.hd {
	display: var(--bhd);
}

#briwrap {
	float: right;
	margin-top: var(--bmt);
}

#picker {
	margin: 10px auto;
	width: 260px;
}

#rgbwrap {
	display: none;
}

.btn {
	padding: 8px;
	margin: 10px;
	width: 230px;
	font-size: 19px;
	background-color: var(--c-3);
	color: var(--c-f);
	border: 0px solid white;
	border-radius: 25px;
	transition-duration: 0.5s;
	-webkit-backface-visibility: hidden;
	-webkit-transform:translate3d(0,0,0);
}

.btn-s {
	padding: 9px;
	width: 276px;
	background-color: var(--c-2);
}
.btn-i {
	padding-bottom: 3px;
}
.btn-icon {
	margin: 0px 8px 4px 0;
	vertical-align: middle;
}
.btna-icon {
	margin: 0px;
}
.btn-p {
	width: 216px;
}

#qcs-w {
	margin-top: 10px;
}
.qcs {
	padding: 14px;
	margin: 2px;
	border-radius: 14px;
	display: inline-block;
}
.qcsb {
	padding: 13px;
	border: 1px solid var(--c-f);
}
#hexw {
	margin-top: 5px;
	display: none;
}

.cl {
	width: 42px;
}

select {
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='white'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat;
	background-size: 12px;
	background-position: 206px 16px;
	padding-left: 12px !important;
	background-repeat: no-repeat;
	outline: none;
}
select:-moz-focusring {
	transition-duration: 0s;
	color: transparent;
	text-shadow: 0 0 0 #fff;
}
option {
	background-color: var(--c-3);
	color: var(--c-f);
}

input[type=number], input[type=text] {
	background: var(--c-3);
	color: var(--c-f);
	border: 0px solid white;
	border-radius: 5px;
	padding: 8px;
	margin: 6px 6px 6px 0;
	font-size: 19px;
	transition: background-color 0.2s;
	outline: none;
	width: 50px;
	-webkit-appearance: textfield;
		 -moz-appearance: textfield;
					appearance: textfield;
}

textarea {
	background: var(--c-2);
	color: var(--c-f);
	width: 236px;
	height: 90px;
	border-radius: 5px;
	border: 2px solid #555;
	outline: none;
	resize: none;
	font-size: 19px;
}

::selection {
  background: var(--c-b);
}

input[type=text] {
	width: 100px;
	border-radius: 25px;
	text-align: center;
}

.ptxt {
	width: 200px !important;
	margin: 26px 0 6px 12px !important;
}

.stxt {
	width: 50px !important;
}

input[type=number]:focus, input[type=text]:focus {
	background: var(--c-6);
}

input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button { 
	-webkit-appearance: none;
}

.segn {
	margin: 3px 0 6px 0 !important;
}

.segname {
	position: absolute;
	top: 0px;
	left: 50%;
	padding: 9px 0;
	transform: translateX(-50%);
	white-space: nowrap;
	cursor: pointer;
}

.pname {
	width: 208px;
	padding: 8px 0;
	text-align: center;
	overflow: hidden;
	text-overflow: clip;
}

.newseg {
	cursor: default;
}

.ic {
	padding: 6px 0 0 0;
}

.xxs {
	width: 40px;
	margin: 6px;
}

.psts {
	background-color: var(--c-3);
	color: var(--c-f);
	cursor: pointer;
	padding: 2px 0 0 0;
	height: 40px;
}

.cnf {
	color: var(--c-f);
	cursor: pointer;
	background: var(--c-3);
	border-radius: 5px;
}

.cnf-s {
	position: absolute;
	top: 66px;
	right: 28px;
	padding: 43px 6px;
}

.pwr {
	color: var(--c-6); 
	transform: translate(2px, 3px);
	cursor: pointer;
}

.act {
	color: var(--c-f);
}

.half {
	padding: 7.5px;
	top: 64px;
}

.del {
	position: absolute;
	bottom: 8px;
	right: 8px;
	color: var(--c-f);
	cursor: pointer;
}

.check {
	display: inline-block;
	position: relative;
	padding-bottom: 32px;
	margin-bottom: 14px;
	cursor: pointer;
	text-align: center;
}

.schkl {
	padding: 2px 22px 0px 35px;
	margin: 0 0 0 2px;
}

.revchkl {
	padding: 2px 0px 0px 35px;
	margin-bottom: 0px;
	margin-top: 8px;
}

.check input {
	position: absolute;
	opacity: 0;
	cursor: pointer;
	height: 0;
	width: 0;
}

.checkmark {
	position: absolute;
	bottom: 0;
	left: 0;
	height: 25px;
	width: 25px;
	background-color: var(--c-3);
	border-radius: 10px;
}

.schk {
	top: 0;
}

.psv {
	left: initial;
	bottom: initial;
	top: 0;
	right: 0;
}

.psvl {
	padding: 2px 35px 10px 0px;
	margin-top: 10px;
	margin-bottom: 0px;
}


.check:hover input ~ .checkmark {
	background-color: var(--c-4);
}

.check input:checked ~ .checkmark {
	background-color: var(--c-6);
}

.checkmark:after {
	content: "";
	position: absolute;
	display: none;
}

.check input:checked ~ .checkmark:after {
	display: block;
}

.check .checkmark:after {
	left: 9px;
	top: 5px;
	width: 5px;
	height: 10px;
	border: solid var(--c-f);
	border-width: 0 3px 3px 0;
	-webkit-transform: rotate(45deg);
	-ms-transform: rotate(45deg);
	transform: rotate(45deg);
}

.h {
	font-size: 13px;
	text-align: center;
	color: var(--c-b);
}

.bp {
	margin-bottom: 5px;
}

.seg {
	position: relative;
	display: inline-block;
	padding: 8px;
	margin: 10px;
	width: 260px;
	font-size: 19px;
	background-color: var(--c-2);
	color: var(--c-f);
	border: 0px solid white;
	border-radius: 20px;
	text-align: left;
	transition: background-color 0.5s;
  filter: brightness(1);
}

.pres {
	margin-bottom: 6px;
}

.segin {
	padding: 8px 8px 4px 8px;
	display: none;
}

.expanded {
	display: block;
}

.c {
	text-align: center;
}

.po2 {
	display: none;
	margin-top: 8px;
}

.pwarn {
	color: red;
}

::-webkit-scrollbar {
	width: 6px;
}
::-webkit-scrollbar-track {
	background: transparent; 
}
::-webkit-scrollbar-thumb {
	background: var(--c-sb);
	opacity: 0.2;
	border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
	background: var(--c-sbh);
}

@media all and (max-width: 335px) {
	.sliderbubble {
    display: none;
  }
}

@media all and (max-width: 550px) and (min-width: 374px) {
	.infobtn {
		width: 155px;
	}
}

@media all and (max-width: 685px) {
	.top button {
		width: 16.6%;
		padding: 8px 0 4px 0;
	}
	.hd {
		display: none !important;
	}
	#briwrap {
		margin-top: 0px !important;
		float: none;
	}
}

@media all and (max-width: 1249px) {
	#buttonPcm {
	display: none;
	}
}
</style>
</head>
<body onload="onLoad()">

<div id="cv" class="overlay">Loading WLED UI...</div>
<noscript><div class="overlay" style="opacity:1;">Sorry, WLED UI needs JavaScript!</div></noscript>
<div id="bg"></div>

<div class="wrapper" id="top">
	<div class="tab top">
		<div class="btnwrap">
			<button id="buttonPower" onclick="togglePower()" class="tgl"><i class="icons">&#xe08f;</i><p class="tab-label">Power</p></button>
			<button id="buttonNl" onclick="toggleNl()"><i class="icons">&#xe2a2;</i><p class="tab-label">Timer</p></button>
			<button id="buttonSync" onclick="toggleSync()"><i class="icons">&#xe116;</i><p class="tab-label">Sync</p></button>
			<button id="buttonSr" onclick="toggleLiveview()"><i class="icons">&#xe410;</i><p class="tab-label">Peek</p></button>
		<button id="buttonI" onclick="toggleInfo()"><i class="icons">&#xe34b;</i><p class="tab-label">Info</p></button>
			<button onclick="window.location.href = '/settings';"><i class="icons">&#xe0a2;</i><p class="tab-label">Config</p></button>
		<button id="buttonPcm" onclick="togglePcMode(true)"><i class="icons">&#xe23d;</i><p class="tab-label">PC Mode</p></button>
		</div>
		<div id="briwrap">
			<p class="hd">Brightness</p>
			<div class="il">
				<i class="icons slider-icon" onclick="tglTheme()">&#xe2a6;</i>
				<div class="sliderwrap il">
					<input id="sliderBri" onchange="setBri()" oninput="updateTrail(this)" max="255" min="1" type="range" value="128" />
					<div class="sliderdisplay"></div>
				</div>
			</div>
		</div>
		<iframe id="liveview" src="about:blank"></iframe>
	</div>
</div>

<div class ="container">
	<div id="Colors" class="tabcontent">
		<div id="picker" class="noslide"></div>
		<div id="rgbwrap">
			<div class="sliderwrap il">
				<input id="sliderR" class="noslide" onchange="fromRgb()" oninput="updateTrail(this,1)" max="255" min="0" type="range" value="128" />
				<div class="sliderdisplay"></div>
			</div><br>
			<div class="sliderwrap il">
				<input id="sliderG" class="noslide" onchange="fromRgb()" oninput="updateTrail(this,2)" max="255" min="0" type="range" value="128" />
				<div class="sliderdisplay"></div>
			</div><br>
			<div class="sliderwrap il">
				<input id="sliderB" class="noslide" onchange="fromRgb()" oninput="updateTrail(this,3)" max="255" min="0" type="range" value="128" />
				<div class="sliderdisplay"></div>
			</div><br>
		</div>
		<div id="wwrap">
			<p class="labels">White channel</p>
			<div class="sliderwrap il">
				<input id="sliderW" class="noslide" onchange="setColor(0)" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
				<div class="sliderdisplay"></div>
			</div>
		</div>
		<div id="qcs-w">
			<div class="qcs" onclick="pC('#ff0000');" style="background-color:#ff0000;"></div>
			<div class="qcs" onclick="pC('#ffa000');" style="background-color:#ffa000;"></div>
			<div class="qcs" onclick="pC('#ffc800');" style="background-color:#ffc800;"></div>
			<div class="qcs" onclick="pC('#ffe0a0');" style="background-color:#ffe0a0;"></div>
			<div class="qcs" onclick="pC('#ffffff');" style="background-color:#ffffff;"></div>
			<div class="qcs qcsb" onclick="pC('#000000');" style="background-color:#000000;"></div><br>
			<div class="qcs" onclick="pC('#ff00ff');" style="background-color:#ff00ff;"></div>
			<div class="qcs" onclick="pC('#0000ff');" style="background-color:#0000ff;"></div>
			<div class="qcs" onclick="pC('#00ffc8');" style="background-color:#00ffc8;"></div>
			<div class="qcs" onclick="pC('#08ff00');" style="background-color:#08ff00;"></div>
			<div class="qcs" onclick="pC('rnd');" style="background-color:var(--c-3); padding: 4px 8px; transform: translateY(-10px);">R</div>
		</div>
		<div id="csl">
			<button class="xxs cl btn" onclick="selectSlot(0);">1</button>
			<button class="xxs cl btn" onclick="selectSlot(1);">2</button>
			<button class="xxs cl btn" onclick="selectSlot(2);">3</button>
		</div>
		<div id="hexw">
			<input id="hexc" type="text" class="noslide" onkeydown="hexEnter(this)" autocomplete="off" maxlength="8" />
			<button id="hexcnf" class="xxs btn" onclick="fromHex();"><i class="icons btna-icon">&#xe390;</i></button>
		</div>
		<p class="labels">Color palette</p> 
		<div class="il">
			<i class="icons sel-icon" onclick="tglHex()">&#xe2b3;</i>
			<select class="btn sel" id="selectPalette" onchange="setPalette()">
				<option>Default</option>
				<option>Error!</option>
			</select>
		</div>
	</div>

	<div id="Effects" class="tabcontent">
		<p class="labels">Effect speed</p>
		<div class="staytop">
			<i class="icons slider-icon">&#xe325;</i>
			<div class="sliderwrap il">
				<input id="sliderSpeed" class="noslide" onchange="setSpeed()" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
				<output class="sliderbubble hidden"></output>
				<div class="sliderdisplay"></div>
			</div>
		</div>
		<p class="labels">Effect intensity</p>
		<div class="staytop" id="staytop1">
			<i class="icons slider-icon" onclick="tglLabels()">&#xe409;</i>
			<div class="sliderwrap il">
				<input id="sliderIntensity" class="noslide" onchange="setIntensity()" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
				<output class="sliderbubble hidden"></output>
				<div class="sliderdisplay"></div>
			</div>
		</div>
		<p class="labels">Effect mode</p>
		<div class="staytop" id="staytop2">
			<button class="btn" id="fxb0" onclick="setX(0);">Solid</button>
		</div>
		<div id="fxlist">
			Loading...
		</div>
		<br>
	</div>
	
	<div id="Segments" class="tabcontent">
		<div id="segcont">
			Loading...
		</div>
		<div id="segutil">
			
		</div>
		<div id="segutil2">
			<button class="btn btn-s" id="rsbtn" onclick="rSegs()">Reset segments</button>
		</div>
	</div>

	<div id="Favorites" class="tabcontent">
		<div id="putil">
			
		</div>
		<div id="pql">

		</div>
		<div id="pcont">
			Loading...
		</div><br>
		 <label class="check psvl">
			Preset cycle
			<input type="checkbox" id="cyToggle" onchange="toggleCY()">
			<span class="checkmark psv"></span>
		</label><br>
		First preset: <input id="cycs" class="noslide" type="number" min="1" max="249" value="1"><br>
		Last preset: <input id="cyce" class="noslide" type="number" min="2" max="250" value="3"><br>
		Time per preset: <input id="cyct" class="noslide" type="number" min="0.2" max="6553.5" step="0.1" value="1.2">s<br>
		Transition: <input id="cyctt" class="noslide" type="number" min="0" max="65.5" step="0.1" value="0.7">s
	</div>
</div>

<div class="tab bot" id="bot">
	<button class="tablinks" onclick="openTab(0)"><i class="icons">&#xe2b3;</i><p class="tab-label">Colors</p></button>
	<button class="tablinks" onclick="openTab(1)"><i class="icons">&#xe23d;</i><p class="tab-label">Effects</p></button>
	<button class="tablinks" onclick="openTab(2)"><i class="icons">&#xe34b;</i><p class="tab-label">Segments</p></button>
	<button class="tablinks" onclick="openTab(3)"><i class="icons">&#xe04c;</i><p class="tab-label">Favorites</p></button>
</div>

<div id="connind"></div>
<div id="toast"></div>
<div id="namelabel"></div>
<div id="info" class="modal">
	<div id="imgw">
		<img alt="" src="">
	</div><br>
<div id="kv">Loading...</div><br>
<button class="btn infobtn" onclick="requestJson(null)">Refresh</button>
<button class="btn infobtn" onclick="toggleInfo()">Close Info</button><br>
<button class="btn infobtn" onclick="openGH()">WLED Wiki</button>
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button><br>
<span class="h">Made with <span id="heart">&#10084;&#xFE0E;</span> by Aircoookie and the WLED community</span>
</div>

<div id="rover" class="modal">
	<i class="icons huge">&#xe410;</i><br>
	<div id="lv">?</div><br><br>
	To use built-in effects, use an override button below.<br>
	You can return to realtime mode by pressing the star in the top left corner.<br>
	<button class="btn" onclick="setLor(1)">Override once</button>
	<button class="btn" onclick="setLor(2)">Override until reboot</button><br>
	<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
</div>
<i id="roverstar" class="icons huge" onclick="setLor(0)">&#xe410;</i><br>
<script>
/*!
 * iro.js v5.2.3
 * 2016-2020 James Daniel
 * Licensed under MPL 2.0
 * github.com/jaames/iro.js
 */
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(n=n||self).iro=t()}(this,function(){"use strict";var m,s,t,i,o,k={},M=[],r=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/i;function j(n,t){for(var i in t)n[i]=t[i];return n}function y(n){var t=n.parentNode;t&&t.removeChild(n)}function d(n,t,i){var r,e,u,o,l=arguments;if(t=j({},t),3<arguments.length)for(i=[i],r=3;r<arguments.length;r++)i.push(l[r]);if(null!=i&&(t.children=i),null!=n&&null!=n.defaultProps)for(e in n.defaultProps)void 0===t[e]&&(t[e]=n.defaultProps[e]);return o=t.key,null!=(u=t.ref)&&delete t.ref,null!=o&&delete t.key,c(n,t,o,u)}function c(n,t,i,r){var e={type:n,props:t,key:i,ref:r,n:null,i:null,e:0,o:null,l:null,c:null,constructor:void 0};return m.vnode&&m.vnode(e),e}function O(n){return n.children}function I(n,t){this.props=n,this.context=t}function w(n,t){if(null==t)return n.i?w(n.i,n.i.n.indexOf(n)+1):null;for(var i;t<n.n.length;t++)if(null!=(i=n.n[t])&&null!=i.o)return i.o;return"function"==typeof n.type?w(n):null}function f(n){var t,i;if(null!=(n=n.i)&&null!=n.c){for(n.o=n.c.base=null,t=0;t<n.n.length;t++)if(null!=(i=n.n[t])&&null!=i.o){n.o=n.c.base=i.o;break}return f(n)}}function e(n){(!n.f&&(n.f=!0)&&1===s.push(n)||i!==m.debounceRendering)&&(i=m.debounceRendering,(m.debounceRendering||t)(u))}function u(){var n,t,i,r,e,u,o,l;for(s.sort(function(n,t){return t.p.e-n.p.e});n=s.pop();)n.f&&(r=i=void 0,u=(e=(t=n).p).o,o=t.w,l=t.u,t.u=!1,o&&(i=[],r=x(o,e,j({},e),t.m,void 0!==o.ownerSVGElement,null,i,l,null==u?w(e):u),v(i,e),r!=u&&f(e)))}function A(t,i,n,r,e,u,o,l,s){var c,f,a,h,v,d,g,b=n&&n.n||M,p=b.length;if(l==k&&(l=null!=u?u[0]:p?w(n,0):null),c=0,i.n=S(i.n,function(n){if(null!=n){if(n.i=i,n.e=i.e+1,null===(a=b[c])||a&&n.key==a.key&&n.type===a.type)b[c]=void 0;else for(f=0;f<p;f++){if((a=b[f])&&n.key==a.key&&n.type===a.type){b[f]=void 0;break}a=null}if(h=x(t,n,a=a||k,r,e,u,o,null,l,s),(f=n.ref)&&a.ref!=f&&(g=g||[]).push(f,n.c||h,n),null!=h){if(null==d&&(d=h),null!=n.l)h=n.l,n.l=null;else if(u==a||h!=l||null==h.parentNode){n:if(null==l||l.parentNode!==t)t.appendChild(h);else{for(v=l,f=0;(v=v.nextSibling)&&f<p;f+=2)if(v==h)break n;t.insertBefore(h,l)}"option"==i.type&&(t.value="")}l=h.nextSibling,"function"==typeof i.type&&(i.l=h)}}return c++,n}),i.o=d,null!=u&&"function"!=typeof i.type)for(c=u.length;c--;)null!=u[c]&&y(u[c]);for(c=p;c--;)null!=b[c]&&R(b[c],b[c]);if(g)for(c=0;c<g.length;c++)N(g[c],g[++c],g[++c])}function S(n,t,i){if(null==i&&(i=[]),null==n||"boolean"==typeof n)t&&i.push(t(null));else if(Array.isArray(n))for(var r=0;r<n.length;r++)S(n[r],t,i);else i.push(t?t(function(n){if(null==n||"boolean"==typeof n)return null;if("string"==typeof n||"number"==typeof n)return c(null,n,null,null);if(null==n.o&&null==n.c)return n;var t=c(n.type,n.props,n.key,null);return t.o=n.o,t}(n)):n);return i}function a(n,t,i){"-"===t[0]?n.setProperty(t,i):n[t]="number"==typeof i&&!1===r.test(t)?i+"px":null==i?"":i}function E(n,t,i,r,e){var u,o,l,s,c;if("key"===(t=e?"className"===t?"class":t:"class"===t?"className":t)||"children"===t);else if("style"===t)if(u=n.style,"string"==typeof i)u.cssText=i;else{if("string"==typeof r&&(u.cssText="",r=null),r)for(o in r)i&&o in i||a(u,o,"");if(i)for(l in i)r&&i[l]===r[l]||a(u,l,i[l])}else"o"===t[0]&&"n"===t[1]?(s=t!==(t=t.replace(/Capture$/,"")),t=((c=t.toLowerCase())in n?c:t).slice(2),i?(r||n.addEventListener(t,h,s),(n.t||(n.t={}))[t]=i):n.removeEventListener(t,h,s)):"list"!==t&&"tagName"!==t&&"form"!==t&&!e&&t in n?n[t]=null==i?"":i:"function"!=typeof i&&"dangerouslySetInnerHTML"!==t&&(t!==(t=t.replace(/^xlink:?/,""))?null==i||!1===i?n.removeAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase()):n.setAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase(),i):null==i||!1===i?n.removeAttribute(t):n.setAttribute(t,i))}function h(n){return this.t[n.type](m.event?m.event(n):n)}function x(n,t,i,r,e,u,o,l,s,c){var f,a,h,v,d,g,b,p,y,w,x=t.type;if(void 0!==t.constructor)return null;(f=m.e)&&f(t);try{n:if("function"==typeof x){if(p=t.props,y=(f=x.contextType)&&r[f.c],w=f?y?y.props.value:f.i:r,i.c?b=(a=t.c=i.c).i=a.k:("prototype"in x&&x.prototype.render?t.c=a=new x(p,w):(t.c=a=new I(p,w),a.constructor=x,a.render=_),y&&y.sub(a),a.props=p,a.state||(a.state={}),a.context=w,a.m=r,h=a.f=!0,a.M=[]),null==a.j&&(a.j=a.state),null!=x.getDerivedStateFromProps&&j(a.j==a.state?a.j=j({},a.j):a.j,x.getDerivedStateFromProps(p,a.j)),h)null==x.getDerivedStateFromProps&&null!=a.componentWillMount&&a.componentWillMount(),null!=a.componentDidMount&&o.push(a);else{if(null==x.getDerivedStateFromProps&&null==l&&null!=a.componentWillReceiveProps&&a.componentWillReceiveProps(p,w),!l&&null!=a.shouldComponentUpdate&&!1===a.shouldComponentUpdate(p,a.j,w)){for(a.props=p,a.state=a.j,a.f=!1,(a.p=t).o=null!=s?s!==i.o?s:i.o:null,t.n=i.n,f=0;f<t.n.length;f++)t.n[f]&&(t.n[f].i=t);break n}null!=a.componentWillUpdate&&a.componentWillUpdate(p,a.j,w)}for(v=a.props,d=a.state,a.context=w,a.props=p,a.state=a.j,(f=m.O)&&f(t),a.f=!1,a.p=t,a.w=n,f=a.render(a.props,a.state,a.context),t.n=S(null!=f&&f.type==O&&null==f.key?f.props.children:f),null!=a.getChildContext&&(r=j(j({},r),a.getChildContext())),h||null==a.getSnapshotBeforeUpdate||(g=a.getSnapshotBeforeUpdate(v,d)),A(n,t,i,r,e,u,o,s,c),a.base=t.o;f=a.M.pop();)a.j&&(a.state=a.j),f.call(a);h||null==v||null==a.componentDidUpdate||a.componentDidUpdate(v,d,g),b&&(a.k=a.i=null)}else t.o=function(n,t,i,r,e,u,o,l){var s,c,f,a,h=i.props,v=t.props;if(e="svg"===t.type||e,null==n&&null!=u)for(s=0;s<u.length;s++)if(null!=(c=u[s])&&(null===t.type?3===c.nodeType:c.localName===t.type)){n=c,u[s]=null;break}if(null==n){if(null===t.type)return document.createTextNode(v);n=e?document.createElementNS("http://www.w3.org/2000/svg",t.type):document.createElement(t.type),u=null}return null===t.type?h!==v&&(null!=u&&(u[u.indexOf(n)]=null),n.data=v):t!==i&&(null!=u&&(u=M.slice.call(n.childNodes)),f=(h=i.props||k).dangerouslySetInnerHTML,a=v.dangerouslySetInnerHTML,l||(a||f)&&(a&&f&&a.I==f.I||(n.innerHTML=a&&a.I||"")),function(n,t,i,r,e){var u;for(u in i)u in t||E(n,u,null,i[u],r);for(u in t)e&&"function"!=typeof t[u]||"value"===u||"checked"===u||i[u]===t[u]||E(n,u,t[u],i[u],r)}(n,v,h,e,l),t.n=t.props.children,a||A(n,t,i,r,"foreignObject"!==t.type&&e,u,o,k,l),l||("value"in v&&void 0!==v.value&&v.value!==n.value&&(n.value=null==v.value?"":v.value),"checked"in v&&void 0!==v.checked&&v.checked!==n.checked&&(n.checked=v.checked))),n}(i.o,t,i,r,e,u,o,c);(f=m.diffed)&&f(t)}catch(n){m.o(n,t,i)}return t.o}function v(n,t){for(var i;i=n.pop();)try{i.componentDidMount()}catch(n){m.o(n,i.p)}m.c&&m.c(t)}function N(n,t,i){try{"function"==typeof n?n(t):n.current=t}catch(n){m.o(n,i)}}function R(n,t,i){var r,e,u;if(m.unmount&&m.unmount(n),(r=n.ref)&&N(r,null,t),i||"function"==typeof n.type||(i=null!=(e=n.o)),n.o=n.l=null,null!=(r=n.c)){if(r.componentWillUnmount)try{r.componentWillUnmount()}catch(n){m.o(n,t)}r.base=r.w=null}if(r=n.n)for(u=0;u<r.length;u++)r[u]&&R(r[u],t,i);null!=e&&y(e)}function _(n,t,i){return this.constructor(n,i)}m={},I.prototype.setState=function(n,t){var i=this.j!==this.state&&this.j||(this.j=j({},this.state));"function"==typeof n&&!(n=n(i,this.props))||j(i,n),null!=n&&this.p&&(this.u=!1,t&&this.M.push(t),e(this))},I.prototype.forceUpdate=function(n){this.p&&(n&&this.M.push(n),this.u=!0,e(this))},I.prototype.render=O,s=[],t="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,i=m.debounceRendering,m.o=function(n,t,i){for(var r;t=t.i;)if((r=t.c)&&!r.i)try{if(r.constructor&&null!=r.constructor.getDerivedStateFromError)r.setState(r.constructor.getDerivedStateFromError(n));else{if(null==r.componentDidCatch)continue;r.componentDidCatch(n)}return e(r.k=r)}catch(t){n=t}throw n},o=k;var n="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)",l="[\\s|\\(]+("+n+")[,|\\s]+("+n+")[,|\\s]+("+n+")\\s*\\)?",g="[\\s|\\(]+("+n+")[,|\\s]+("+n+")[,|\\s]+("+n+")[,|\\s]+("+n+")\\s*\\)?",b=new RegExp("rgb"+l),p=new RegExp("rgba"+g),P=new RegExp("hsl"+l),z=new RegExp("hsla"+g),$="^(?:#?|0x?)",H="([0-9a-fA-F]{1})",T="([0-9a-fA-F]{2})",W=new RegExp($+H+H+H+"$"),C=new RegExp($+H+H+H+H+"$"),D=new RegExp($+T+T+T+"$"),F=new RegExp($+T+T+T+T+"$"),G=Math.log,L=Math.round,B=Math.floor;function U(n,t,i){return Math.min(Math.max(n,t),i)}function q(n,t){var i=-1<n.indexOf("%"),r=parseFloat(n);return i?t/100*r:r}function J(n){return parseInt(n,16)}function K(n){return n.toString(16).padStart(2,"0")}var Q=function(n,t){this.$={h:0,s:0,v:0,a:1},n&&this.set(n),this.onChange=t,this.initialValue=Object.assign({},this.$)},V={hsv:{configurable:!0},hsva:{configurable:!0},hue:{configurable:!0},saturation:{configurable:!0},value:{configurable:!0},alpha:{configurable:!0},kelvin:{configurable:!0},red:{configurable:!0},green:{configurable:!0},blue:{configurable:!0},rgb:{configurable:!0},rgba:{configurable:!0},hsl:{configurable:!0},hsla:{configurable:!0},rgbString:{configurable:!0},rgbaString:{configurable:!0},hexString:{configurable:!0},hex8String:{configurable:!0},hslString:{configurable:!0},hslaString:{configurable:!0}};Q.prototype.set=function(n){if("string"==typeof n)/^(?:#?|0x?)[0-9a-fA-F]{3,8}$/.test(n)?this.hexString=n:/^rgba?/.test(n)?this.rgbString=n:/^hsla?/.test(n)&&(this.hslString=n);else{if("object"!=typeof n)throw new Error("Invalid color value");n instanceof Q?this.hsv=n.hsv:"object"==typeof n&&"r"in n&&"g"in n&&"b"in n?this.rgb=n:"object"==typeof n&&"h"in n&&"s"in n&&"v"in n?this.hsv=n:"object"==typeof n&&"h"in n&&"s"in n&&"l"in n&&(this.hsl=n)}},Q.prototype.setChannel=function(n,t,i){var r;this[n]=Object.assign({},this[n],((r={})[t]=i,r))},Q.prototype.reset=function(){this.hsva=this.initialValue},Q.prototype.clone=function(){return new Q(this)},Q.prototype.unbind=function(){this.onChange=void 0},Q.hsvToRgb=function(n){var t=n.h/60,i=n.s/100,r=n.v/100,e=B(t),u=t-e,o=r*(1-i),l=r*(1-u*i),s=r*(1-(1-u)*i),c=e%6,f=[s,r,r,l,o,o][c],a=[o,o,s,r,r,l][c];return{r:U(255*[r,l,o,o,s,r][c],0,255),g:U(255*f,0,255),b:U(255*a,0,255)}},Q.rgbToHsv=function(n){var t=n.r/255,i=n.g/255,r=n.b/255,e=Math.max(t,i,r),u=Math.min(t,i,r),o=e-u,l=0,s=e,c=0===e?0:o/e;switch(e){case u:l=0;break;case t:l=(i-r)/o+(i<r?6:0);break;case i:l=(r-t)/o+2;break;case r:l=(t-i)/o+4}return{h:60*l%360,s:U(100*c,0,100),v:U(100*s,0,100)}},Q.hsvToHsl=function(n){var t=n.s/100,i=n.v/100,r=(2-t)*i,e=r<=1?r:2-r,u=e<1e-9?0:t*i/e;return{h:n.h,s:U(100*u,0,100),l:U(50*r,0,100)}},Q.hslToHsv=function(n){var t=2*n.l,i=n.s*(t<=100?t:200-t)/100,r=t+i<1e-9?0:2*i/(t+i);return{h:n.h,s:U(100*r,0,100),v:U((t+i)/2,0,100)}},Q.kelvinToRgb=function(n){var t,i,r,e=n/100;return r=e<66?(t=255,i=-155.25485562709179-.44596950469579133*(i=e-2)+104.49216199393888*G(i),e<20?0:.8274096064007395*(r=e-10)-254.76935184120902+115.67994401066147*G(r)):(t=351.97690566805693+.114206453784165*(t=e-55)-40.25366309332127*G(t),i=325.4494125711974+.07943456536662342*(i=e-50)-28.0852963507957*G(i),255),{r:U(B(t),0,255),g:U(B(i),0,255),b:U(B(r),0,255)}},Q.rgbToKelvin=function(n){for(var t,i=n.r,r=n.b,e=1e3,u=4e4;.4<u-e;){t=.5*(u+e);var o=Q.kelvinToRgb(t);o.b/o.r>=r/i?u=t:e=t}return t},V.hsv.get=function(){var n=this.$;return{h:n.h,s:n.s,v:n.v}},V.hsv.set=function(n){var t=this.$;if(n=Object.assign({},t,n),this.onChange){var i={h:!1,v:!1,s:!1,a:!1};for(var r in t)i[r]=n[r]!=t[r];this.$=n,(i.h||i.s||i.v||i.a)&&this.onChange(this,i)}else this.$=n},V.hsva.get=function(){return Object.assign({},this.$)},V.hsva.set=function(n){this.hsv=n},V.hue.get=function(){return this.$.h},V.hue.set=function(n){this.hsv={h:n}},V.saturation.get=function(){return this.$.s},V.saturation.set=function(n){this.hsv={s:n}},V.value.get=function(){return this.$.v},V.value.set=function(n){this.hsv={v:n}},V.alpha.get=function(){return this.$.a},V.alpha.set=function(n){this.hsv=Object.assign({},this.hsv,{a:n})},V.kelvin.get=function(){return Q.rgbToKelvin(this.rgb)},V.kelvin.set=function(n){this.rgb=Q.kelvinToRgb(n)},V.red.get=function(){return this.rgb.r},V.red.set=function(n){this.rgb=Object.assign({},this.rgb,{r:n})},V.green.get=function(){return this.rgb.g},V.green.set=function(n){this.rgb=Object.assign({},this.rgb,{g:n})},V.blue.get=function(){return this.rgb.b},V.blue.set=function(n){this.rgb=Object.assign({},this.rgb,{b:n})},V.rgb.get=function(){var n=Q.hsvToRgb(this.$),t=n.r,i=n.g,r=n.b;return{r:L(t),g:L(i),b:L(r)}},V.rgb.set=function(n){this.hsv=Object.assign({},Q.rgbToHsv(n),{a:void 0===n.a?1:n.a})},V.rgba.get=function(){return Object.assign({},this.rgb,{a:this.alpha})},V.rgba.set=function(n){this.rgb=n},V.hsl.get=function(){var n=Q.hsvToHsl(this.$),t=n.h,i=n.s,r=n.l;return{h:L(t),s:L(i),l:L(r)}},V.hsl.set=function(n){this.hsv=Object.assign({},Q.hslToHsv(n),{a:void 0===n.a?1:n.a})},V.hsla.get=function(){return Object.assign({},this.hsl,{a:this.alpha})},V.hsla.set=function(n){this.hsl=n},V.rgbString.get=function(){var n=this.rgb;return"rgb("+n.r+", "+n.g+", "+n.b+")"},V.rgbString.set=function(n){var t,i,r,e,u=1;if((t=b.exec(n))?(i=q(t[1],255),r=q(t[2],255),e=q(t[3],255)):(t=p.exec(n))&&(i=q(t[1],255),r=q(t[2],255),e=q(t[3],255),u=q(t[4],1)),!t)throw new Error("Invalid rgb string");this.rgb={r:i,g:r,b:e,a:u}},V.rgbaString.get=function(){var n=this.rgba;return"rgba("+n.r+", "+n.g+", "+n.b+", "+n.a+")"},V.rgbaString.set=function(n){this.rgbString=n},V.hexString.get=function(){var n=this.rgb;return"#"+K(n.r)+K(n.g)+K(n.b)},V.hexString.set=function(n){var t,i,r,e,u=255;if((t=W.exec(n))?(i=17*J(t[1]),r=17*J(t[2]),e=17*J(t[3])):(t=C.exec(n))?(i=17*J(t[1]),r=17*J(t[2]),e=17*J(t[3]),u=17*J(t[4])):(t=D.exec(n))?(i=J(t[1]),r=J(t[2]),e=J(t[3])):(t=F.exec(n))&&(i=J(t[1]),r=J(t[2]),e=J(t[3]),u=J(t[4])),!t)throw new Error("Invalid hex string");this.rgb={r:i,g:r,b:e,a:u/255}},V.hex8String.get=function(){var n=this.rgba;return"#"+K(n.r)+K(n.g)+K(n.b)+K(B(255*n.a))},V.hex8String.set=function(n){this.hexString=n},V.hslString.get=function(){var n=this.hsl;return"hsl("+n.h+", "+n.s+"%, "+n.l+"%)"},V.hslString.set=function(n){var t,i,r,e,u=1;if((t=P.exec(n))?(i=q(t[1],360),r=q(t[2],100),e=q(t[3],100)):(t=z.exec(n))&&(i=q(t[1],360),r=q(t[2],100),e=q(t[3],100),u=q(t[4],1)),!t)throw new Error("Invalid hsl string");this.hsl={h:i,s:r,l:e,a:u}},V.hslaString.get=function(){var n=this.hsla;return"hsl("+n.h+", "+n.s+"%, "+n.l+"%, "+n.a+")"},V.hslaString.set=function(n){this.hslString=n},Object.defineProperties(Q.prototype,V);var X;function Y(n){var t=n.width,i=n.sliderSize,r=n.borderWidth,e=n.handleRadius,u=n.padding,o=n.sliderShape,l="horizontal"===n.layoutDirection;return i=i||2*u+2*e+2*r,"circle"===o?{handleStart:n.padding+n.handleRadius,handleRange:t-2*u-2*e-2*r,width:t,height:t,cx:t/2,cy:t/2,radius:t/2-r/2}:{handleStart:i/2,handleRange:t-i,radius:i/2,x:0,y:0,width:l?i:t,height:l?t:i}}function Z(n,t){var i=Y(n),r=i.width,e=i.height,u=i.handleRange,o=i.handleStart,l="horizontal"===n.layoutDirection,s=l?r/2:e/2,c=o+function(n,t){var i=t.hsva,r=t.rgb;switch(n.sliderType){case"red":return r.r/2.55;case"green":return r.g/2.55;case"blue":return r.b/2.55;case"alpha":return 100*i.a;case"kelvin":var e=n.minTemperature,u=n.maxTemperature-e,o=(t.kelvin-e)/u*100;return Math.max(0,Math.min(o,100));case"hue":return i.h/=3.6;case"saturation":return i.s;case"value":default:return i.v}}(n,t)/100*u;return l&&(c=-1*c+u+2*o),{x:l?s:c,y:l?c:s}}function nn(n){var t=n.width/2;return{width:n.width,radius:t-n.borderWidth,cx:t,cy:t}}function tn(n,t,i){var r=n.wheelAngle,e=n.wheelDirection;return((t=!i&&"clockwise"===e||i&&"anticlockwise"===e?(i?180:360)-(r-t):r+t)%360+360)%360}function rn(n,t,i){var r=nn(n),e=r.cx,u=r.cy,o=n.width/2-n.padding-n.handleRadius-n.borderWidth;t=e-t,i=u-i;var l=tn(n,Math.atan2(-i,-t)*(180/Math.PI)),s=Math.min(Math.sqrt(t*t+i*i),o);return{h:Math.round(l),s:Math.round(100/o*s)}}function en(n){var t=n.width;return{width:t,height:t,radius:n.padding+n.handleRadius}}function un(n,t,i){var r=en(n),e=r.width,u=r.height,o=r.radius,l=(t-o)/(e-2*o)*100,s=(i-o)/(u-2*o)*100;return{s:Math.max(0,Math.min(l,100)),v:Math.max(0,Math.min(100-s,100))}}function on(n){X=X||document.getElementsByTagName("base");var t=window.navigator.userAgent,i=/^((?!chrome|android).)*safari/i.test(t),r=/iPhone|iPod|iPad/i.test(t),e=window.location;return(i||r)&&0<X.length?e.protocol+"//"+e.host+e.pathname+e.search+n:n}function ln(n,t,i,r){for(var e=0;e<r.length;e++){var u=r[e].x-t,o=r[e].y-i;if(Math.sqrt(u*u+o*o)<n.handleRadius)return e}return null}var sn=["mousemove","touchmove","mouseup","touchend"],cn=function(t){function n(n){t.call(this,n),this.uid=(Math.random()+1).toString(36).substring(5)}return t&&(n.__proto__=t),((n.prototype=Object.create(t&&t.prototype)).constructor=n).prototype.render=function(n){var t=this.handleEvent.bind(this),i={onMouseDown:t,ontouchstart:t},r="horizontal"===n.layoutDirection,e=null===n.margin?n.sliderMargin:n.margin,u={overflow:"visible",display:r?"inline-block":"block"};return 0<n.index&&(u[r?"marginLeft":"marginTop"]=e),d(O,null,n.children(this.uid,i,u))},n.prototype.handleEvent=function(n){var t=this,i=this.props.onInput,r=this.base.getBoundingClientRect();n.preventDefault();var e=n.touches?n.changedTouches[0]:n,u=e.clientX-r.left,o=e.clientY-r.top;switch(n.type){case"mousedown":case"touchstart":sn.forEach(function(n){document.addEventListener(n,t,{passive:!1})}),i(u,o,0);break;case"mousemove":case"touchmove":i(u,o,1);break;case"mouseup":case"touchend":i(u,o,2),sn.forEach(function(n){document.removeEventListener(n,t)})}},n}(I);function fn(n){var t=n.r,i=n.url;return d("svg",{className:"IroHandle IroHandle--"+n.index+" "+(n.isActive?"IroHandle--isActive":""),x:n.x,y:n.y,style:{overflow:"visible"}},i&&d("use",Object.assign({xlinkHref:on(i)},n.props)),!i&&d("circle",{r:t,fill:"none","stroke-width":2,stroke:"#000"}),!i&&d("circle",{r:t-2,fill:n.fill,"stroke-width":2,stroke:"#fff"}))}function an(e){var n=e.activeIndex,u=void 0!==n&&n<e.colors.length?e.colors[n]:e.color,t=Y(e),r=t.width,o=t.height,l=t.radius,s=Z(e,u),c=function(n,t){var i=t.hsv,r=t.rgb;switch(n.sliderType){case"red":return[[0,"rgb(0,"+r.g+","+r.b+")"],[100,"rgb(255,"+r.g+","+r.b+")"]];case"green":return[[0,"rgb("+r.r+",0,"+r.b+")"],[100,"rgb("+r.r+",255,"+r.b+")"]];case"blue":return[[0,"rgb("+r.r+","+r.g+",0)"],[100,"rgb("+r.r+","+r.g+",255)"]];case"alpha":return[[0,"rgba("+r.r+","+r.g+","+r.b+",0)"],[100,"rgb("+r.r+","+r.g+","+r.b+")"]];case"kelvin":for(var e=[],u=n.minTemperature,o=n.maxTemperature,l=o-u,s=u,c=0;s<o;s+=l/8,c+=1){var f=Q.kelvinToRgb(s),a=f.r,h=f.g,v=f.b;e.push([12.5*c,"rgb("+a+","+h+","+v+")"])}return e;case"hue":return[[0,"#f00"],[16.666,"#ff0"],[33.333,"#0f0"],[50,"#0ff"],[66.666,"#00f"],[83.333,"#f0f"],[100,"#f00"]];case"saturation":var d=Q.hsvToHsl({h:i.h,s:0,v:i.v}),g=Q.hsvToHsl({h:i.h,s:100,v:i.v});return[[0,"hsl("+d.h+","+d.s+"%,"+d.l+"%)"],[100,"hsl("+g.h+","+g.s+"%,"+g.l+"%)"]];case"value":default:var b=Q.hsvToHsl({h:i.h,s:i.s,v:100});return[[0,"#000"],[100,"hsl("+b.h+","+b.s+"%,"+b.l+"%)"]]}}(e,u),f="alpha"===e.sliderType;return d(cn,Object.assign({},e,{onInput:function(n,t,i){var r=function(n,t,i){var r,e=Y(n),u=e.handleRange,o=e.handleStart;r="horizontal"===n.layoutDirection?-1*i+u+o:t-o,r=Math.max(Math.min(r,u),0);var l=Math.round(100/u*r);switch(n.sliderType){case"kelvin":var s=n.minTemperature;return s+l/100*(n.maxTemperature-s);case"alpha":return l/100;case"hue":return 3.6*l;case"red":case"blue":case"green":return 2.55*l;default:return l}}(e,n,t);e.parent.inputActive=!0,u[e.sliderType]=r,e.onInput(i)}}),function(n,t,i){return d("svg",Object.assign({},t,{className:"IroSlider",width:r,height:o,style:i}),d("defs",null,d("linearGradient",Object.assign({id:"g"+n},function(n){var t="horizontal"===n.layoutDirection;return{x1:"0%",y1:t?"100%":"0%",x2:t?"0%":"100%",y2:"0%"}}(e)),c.map(function(n){return d("stop",{offset:n[0]+"%","stop-color":n[1]})})),f&&d("pattern",{id:"b"+n,width:"8",height:"8",patternUnits:"userSpaceOnUse"},d("rect",{x:"0",y:"0",width:"8",height:"8",fill:"#fff"}),d("rect",{x:"0",y:"0",width:"4",height:"4",fill:"#ccc"}),d("rect",{x:"4",y:"4",width:"4",height:"4",fill:"#ccc"})),f&&d("pattern",{id:"f"+n,width:"100%",height:"100%"},d("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:"url("+on("#b"+n)+")"}),d("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:"url("+on("#g"+n)+")"}))),d("rect",{className:"IroSliderBg",rx:l,ry:l,x:e.borderWidth/2,y:e.borderWidth/2,width:r-e.borderWidth,height:o-e.borderWidth,"stroke-width":e.borderWidth,stroke:e.borderColor,fill:"url("+on((f?"#f":"#g")+n)+")"}),d(fn,{isActive:!0,index:u.index,r:e.handleRadius,url:e.handleSvg,props:e.handleProps,x:s.x,y:s.y}))})}function hn(e){var n=en(e),r=n.width,u=n.height,o=n.radius,l=e.colors,s=e.parent,t=e.activeIndex,c=void 0!==t&&t<e.colors.length?e.colors[t]:e.color,f=function(n,t){return[[[0,"#fff"],[100,"hsl("+t.hue+",100%,50%)"]],[[0,"rgba(0,0,0,0)"],[100,"#000"]]]}(0,c),a=l.map(function(n){return function(n,t){var i=en(n),r=i.width,e=i.height,u=i.radius,o=t.hsv,l=u,s=r-2*u,c=e-2*u;return{x:l+o.s/100*s,y:l+(c-o.v/100*c)}}(e,n)});return d(cn,Object.assign({},e,{onInput:function(n,t,i){if(0===i){var r=ln(e,n,t,a);null!==r?s.setActiveColor(r):(s.inputActive=!0,c.hsv=un(e,n,t),e.onInput(i))}else 1===i&&(s.inputActive=!0,c.hsv=un(e,n,t));e.onInput(i)}}),function(n,t,i){return d("svg",Object.assign({},t,{className:"IroBox",width:r,height:u,style:i}),d("defs",null,d("linearGradient",{id:"s"+n,x1:"0%",y1:"0%",x2:"100%",y2:"0%"},f[0].map(function(n){return d("stop",{offset:n[0]+"%","stop-color":n[1]})})),d("linearGradient",{id:"l"+n,x1:"0%",y1:"0%",x2:"0%",y2:"100%"},f[1].map(function(n){return d("stop",{offset:n[0]+"%","stop-color":n[1]})})),d("pattern",{id:"f"+n,width:"100%",height:"100%"},d("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:"url("+on("#s"+n)+")"}),d("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:"url("+on("#l"+n)+")"}))),d("rect",{rx:o,ry:o,x:e.borderWidth/2,y:e.borderWidth/2,width:r-e.borderWidth,height:u-e.borderWidth,"stroke-width":e.borderWidth,stroke:e.borderColor,fill:"url("+on("#f"+n)+")"}),l.filter(function(n){return n!==c}).map(function(n){return d(fn,{isActive:!1,index:n.index,fill:n.hslString,r:e.handleRadius,url:e.handleSvg,props:e.handleProps,x:a[n.index].x,y:a[n.index].y})}),d(fn,{isActive:!0,index:c.index,fill:c.hslString,r:e.handleRadius,url:e.handleSvg,props:e.handleProps,x:a[c.index].x,y:a[c.index].y}))})}fn.defaultProps={fill:"none",x:0,y:0,r:8,url:null,props:{x:0,y:0}},an.defaultProps=Object.assign({},{sliderShape:"bar",sliderType:"value",minTemperature:2200,maxTemperature:11e3});var vn=Array.apply(null,{length:360}).map(function(n,t){return t});function dn(e){var n=nn(e),r=n.width,u=n.radius,o=n.cx,l=n.cy,s=e.colors,c=e.borderWidth,f=e.parent,a=e.color,h=a.hsv,v=s.map(function(n){return function(n,t){var i=t.hsv,r=nn(n),e=r.cx,u=r.cy,o=n.width/2-n.padding-n.handleRadius-n.borderWidth,l=(180+tn(n,i.h,!0))*(Math.PI/180),s=i.s/100*o,c="clockwise"===n.wheelDirection?-1:1;return{x:e+s*Math.cos(l)*c,y:u+s*Math.sin(l)*c}}(e,n)});return d(cn,Object.assign({},e,{onInput:function(n,t,i){if(0===i){var r=ln(e,n,t,v);null!==r?f.setActiveColor(r):(f.inputActive=!0,a.hsv=rn(e,n,t),e.onInput(i))}else 1===i&&(f.inputActive=!0,a.hsv=rn(e,n,t));e.onInput(i)}}),function(n,t,i){return d("svg",Object.assign({},t,{className:"IroWheel",width:r,height:r,style:i}),d("defs",null,d("radialGradient",{id:n},d("stop",{offset:"0%","stop-color":"#fff"}),d("stop",{offset:"100%","stop-color":"#fff","stop-opacity":"0"}))),d("g",{className:"IroWheelHue","stroke-width":u,fill:"none"},vn.map(function(n){return d("path",{key:n,d:function(n,t,i,r,e){var u=e-r<=180?0:1;return r*=Math.PI/180,e*=Math.PI/180,"M "+(n+i*Math.cos(e))+" "+(t+i*Math.sin(e))+" A "+i+" "+i+" 0 "+u+" 0 "+(n+i*Math.cos(r))+" "+(t+i*Math.sin(r))}(o,l,u/2,n,n+1.5),stroke:"hsl("+tn(e,n)+", 100%, 50%)"})})),d("circle",{className:"IroWheelSaturation",cx:o,cy:l,r:u,fill:"url("+on("#"+n)+")"}),e.wheelLightness&&d("circle",{className:"IroWheelLightness",cx:o,cy:l,r:u,fill:"#000",opacity:1-h.v/100}),d("circle",{className:"IroWheelBorder",cx:o,cy:l,r:u,fill:"none",stroke:e.borderColor,"stroke-width":c}),s.filter(function(n){return n!==a}).map(function(n){return d(fn,{isActive:!1,index:n.index,fill:n.hslString,r:e.handleRadius,url:e.handleSvg,props:e.handleProps,x:v[n.index].x,y:v[n.index].y})}),d(fn,{isActive:!0,index:a.index,fill:a.hslString,r:e.handleRadius,url:e.handleSvg,props:e.handleProps,x:v[a.index].x,y:v[a.index].y}))})}var gn=function(i){function n(n){var t=this;i.call(this,n),this.colors=[],this.inputActive=!1,this.events={},this.activeEvents={},this.deferredEvents={},this.id=n.id,(0<n.colors.length?n.colors:[n.color]).forEach(function(n){return t.addColor(n)}),this.setActiveColor(0),this.state=Object.assign({},n,{color:this.color,colors:this.colors,layout:n.layout})}return i&&(n.__proto__=i),((n.prototype=Object.create(i&&i.prototype)).constructor=n).prototype.addColor=function(n,t){void 0===t&&(t=this.colors.length);var i=new Q(n,this.onColorChange.bind(this));this.colors.splice(t,0,i),this.colors.forEach(function(n,t){return n.index=t}),this.state&&this.setState({colors:this.colors}),this.deferredEmit("color:init",i)},n.prototype.removeColor=function(n){var t=this.colors.splice(n,1)[0];t.unbind(),this.colors.forEach(function(n,t){return n.index=t}),this.state&&this.setState({colors:this.colors}),t.index===this.color.index&&this.setActiveColor(0),this.emit("color:remove",t)},n.prototype.setActiveColor=function(n){this.color=this.colors[n],this.state&&this.setState({color:this.color}),this.emit("color:setActive",this.color)},n.prototype.setColors=function(n){var t=this;this.colors.forEach(function(n){return n.unbind()}),this.colors=[],n.forEach(function(n){return t.addColor(n)}),this.setActiveColor(0),this.emit("color:setAll",this.colors)},n.prototype.on=function(n,t){var i=this,r=this.events;(Array.isArray(n)?n:[n]).forEach(function(n){(r[n]||(r[n]=[])).push(t),i.deferredEvents[n]&&(i.deferredEvents[n].forEach(function(n){t.apply(null,n)}),i.deferredEvents[n]=[])})},n.prototype.off=function(n,i){var r=this;(Array.isArray(n)?n:[n]).forEach(function(n){var t=r.events[n];t&&t.splice(t.indexOf(i),1)})},n.prototype.emit=function(n){for(var t=this,i=[],r=arguments.length-1;0<r--;)i[r]=arguments[r+1];var e=this.activeEvents;!!e.hasOwnProperty(n)&&e[n]||(e[n]=!0,(this.events[n]||[]).forEach(function(n){return n.apply(t,i)}),e[n]=!1)},n.prototype.deferredEmit=function(n){for(var t,i=[],r=arguments.length-1;0<r--;)i[r]=arguments[r+1];var e=this.deferredEvents;(t=this).emit.apply(t,[n].concat(i)),(e[n]||(e[n]=[])).push(i)},n.prototype.setOptions=function(n){this.setState(Object.assign({},this.state,n))},n.prototype.resize=function(n){this.setOptions({width:n})},n.prototype.reset=function(){this.colors.forEach(function(n){return n.reset()}),this.setState({colors:this.colors})},n.prototype.onMount=function(n){this.el=n,this.deferredEmit("mount",this)},n.prototype.onColorChange=function(n,t){this.setState({color:this.color}),this.inputActive&&(this.inputActive=!1,this.emit("input:change",n,t)),this.emit("color:change",n,t)},n.prototype.emitInputEvent=function(n){0===n?this.emit("input:start",this.color):1===n?this.emit("input:move",this.color):2===n&&this.emit("input:end",this.color)},n.prototype.render=function(n,e){var u=this,t=e.layout;return Array.isArray(t)||(t=[{component:dn},{component:an}],e.transparency&&t.push({component:an,options:{sliderType:"alpha"}})),d("div",{class:"IroColorPicker",id:e.id,style:{display:e.display}},t.map(function(n,t){var i=n.component,r=n.options;return d(i,Object.assign({},e,r,{ref:void 0,onInput:u.emitInputEvent.bind(u),parent:u,index:t}))}))},n}(I);gn.defaultProps=Object.assign({},{width:300,height:300,handleRadius:8,handleSvg:null,handleProps:{x:0,y:0},color:"#fff",colors:[],borderColor:"#fff",borderWidth:0,wheelLightness:!0,wheelAngle:0,wheelDirection:"anticlockwise",layoutDirection:"vertical",sliderSize:null,sliderMargin:12,padding:6},{colors:[],display:"block",id:null,layout:"default",margin:null});var bn,pn,yn,wn,xn=(mn.prototype=(bn=gn).prototype,Object.assign(mn,bn),mn.A=bn,mn);function mn(t,n){var i,r=document.createElement("div");function e(){var n=t instanceof Element?t:document.querySelector(t);n.appendChild(i.base),i.onMount(n)}return function(n,t,i){var r,e,u;m.i&&m.i(n,t),e=(r=i===o)?null:i&&i.n||t.n,n=d(O,null,[n]),u=[],x(t,r?t.n=n:(i||t).n=n,e||k,k,void 0!==t.ownerSVGElement,i&&!r?[i]:e?null:M.slice.call(t.childNodes),u,!1,i||k,r),v(u,n)}(d(bn,Object.assign({},{ref:function(n){return i=n}},n)),r),"loading"!==document.readyState?e():document.addEventListener("DOMContentLoaded",e),i}return(yn=pn=pn||{}).version="5.2.3",yn.Color=Q,yn.ColorPicker=xn,(wn=yn.ui||(yn.ui={})).h=d,wn.ComponentBase=cn,wn.Handle=fn,wn.Slider=an,wn.Wheel=dn,wn.Box=hn,pn});/*!
 * RangeTouch v2.0
 * https://github.com/sampotts/rangetouch
 */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define("RangeTouch",t):e.RangeTouch=t()}(this,function(){"use strict";function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var t={addCSS:!0,thumbWidth:15,watch:!0};var n=function(e){return null!=e?e.constructor:null},r=function(e,t){return!!(e&&t&&e instanceof t)},u=function(e){return null==e},i=function(e){return n(e)===Object},o=function(e){return n(e)===String},a=function(e){return Array.isArray(e)},c=function(e){return r(e,NodeList)},l={nullOrUndefined:u,object:i,number:function(e){return n(e)===Number&&!Number.isNaN(e)},string:o,boolean:function(e){return n(e)===Boolean},function:function(e){return n(e)===Function},array:a,nodeList:c,element:function(e){return r(e,Element)},event:function(e){return r(e,Event)},empty:function(e){return u(e)||(o(e)||a(e)||c(e))&&!e.length||i(e)&&!Object.keys(e).length}};function s(e,t){if(1>t){var n=function(e){var t="".concat(e).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return t?Math.max(0,(t[1]?t[1].length:0)-(t[2]?+t[2]:0)):0}(t);return parseFloat(e.toFixed(n))}return Math.round(e/t)*t}return function(){function n(e,r){(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,n),l.element(e)?this.element=e:l.string(e)&&(this.element=document.querySelector(e)),l.element(this.element)&&l.empty(this.element.rangeTouch)&&(this.config=Object.assign({},t,r),this.init())}return r=n,i=[{key:"setup",value:function(e){var r=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},u=null;if(l.empty(e)||l.string(e)?u=Array.from(document.querySelectorAll(l.string(e)?e:'input[type="range"]')):l.element(e)?u=[e]:l.nodeList(e)?u=Array.from(e):l.array(e)&&(u=e.filter(l.element)),l.empty(u))return null;var i=Object.assign({},t,r);l.string(e)&&i.watch&&new MutationObserver(function(t){Array.from(t).forEach(function(t){Array.from(t.addedNodes).forEach(function(t){l.element(t)&&function(e,t){return function(){return Array.from(document.querySelectorAll(t)).includes(this)}.call(e,t)}(t,e)&&new n(t,i)})})}).observe(document.body,{childList:!0,subtree:!0});return u.map(function(e){return new n(e,r)})}},{key:"enabled",get:function(){return"ontouchstart"in document.documentElement}}],(u=[{key:"init",value:function(){n.enabled&&(this.config.addCSS&&(this.element.style.userSelect="none",this.element.style.webKitUserSelect="none",this.element.style.touchAction="manipulation"),this.listeners(!0),this.element.rangeTouch=this)}},{key:"destroy",value:function(){n.enabled&&(this.listeners(!1),this.element.rangeTouch=null)}},{key:"listeners",value:function(e){var t=this,n=e?"addEventListener":"removeEventListener";["touchstart","touchmove","touchend"].forEach(function(e){t.element[n](e,function(e){return t.set(e)},!1)})}},{key:"get",value:function(e){if(!n.enabled||!l.event(e))return null;var t,r=e.target,u=e.changedTouches[0],i=parseFloat(r.getAttribute("min"))||0,o=parseFloat(r.getAttribute("max"))||100,a=parseFloat(r.getAttribute("step"))||1,c=r.getBoundingClientRect(),f=100/c.width*(this.config.thumbWidth/2)/100;return 0>(t=100/c.width*(u.clientX-c.left))?t=0:100<t&&(t=100),50>t?t-=(100-2*t)*f:50<t&&(t+=2*(t-50)*f),i+s(t/100*(o-i),a)}},{key:"set",value:function(e){n.enabled&&l.event(e)&&!e.target.disabled&&(e.preventDefault(),e.target.value=this.get(e),function(e,t){if(e&&t){var n=new Event(t);e.dispatchEvent(n)}}(e.target,"touchend"===e.type?"change":"input"))}}])&&e(r.prototype,u),i&&e(r,i),n;var r,u,i}()});
//page js
var loc = false, locip;
var ps = false, noNewSegs = false;
var isOn = false, nlA = false, isLv = false, isInfo = false, syncSend = false, syncTglRecv = true, isRgbw = false;
var whites = [0,0,0];
var expanded = [false];
var powered = [true];
var nlDur = 60, nlTar = 0;
var nlFade = false;
var selectedFx = 0;
var csel = 0;
var currentPreset = -1;
var lastUpdate = 0;
var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0;
var pcMode = false, pcModeA = false, lastw = 0;
var d = document;
const ranges = RangeTouch.setup('input[type="range"]', {});
var pJson = {};
var pO = null, pN = "", pI = 0;
var pmt = 1, pmtLS = 0, pmtLast = 0;
var lastinfo = {};
var cfg = {
	theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
	comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false}
};

var cpick = new iro.ColorPicker("#picker", {
	width: 260,
	wheelLightness: false,
  wheelAngle: 90,
  layout: [
    { 
      component: iro.ui.Wheel,
      options: {}
    },
    { 
      component: iro.ui.Slider,
      options: {
        sliderType: 'value'
      }
    },
    { 
      component: iro.ui.Slider,
      options: {
        sliderType: 'kelvin',
        minTemperature: 2100,
        maxTemperature: 10000
      }
    }
  ]
});

function handleVisibilityChange() {
	if (!document.hidden && new Date () - lastUpdate > 3000) {
		requestJson(null);
	}
}

function sCol(na, col) {
	d.documentElement.style.setProperty(na, col);
}

function applyCfg()
{
	cTheme(cfg.theme.base === "light");
	var bg = cfg.theme.color.bg;
	if (bg) sCol('--c-1', bg);
	var ccfg = cfg.comp.colors;
	d.getElementById('hexw').style.display = ccfg.hex ? "block":"none";
	d.getElementById('picker').style.display = ccfg.picker ? "block":"none";
	d.getElementById('rgbwrap').style.display = ccfg.rgb ? "block":"none";
	d.getElementById('qcs-w').style.display = ccfg.quick ? "block":"none";
	var l = cfg.comp.labels;
	var e = d.querySelectorAll('.tab-label');
	for(var i=0; i<e.length; i++)
		e[i].style.display = l ? "block":"none";
	e = d.querySelector('.hd');
	e.style.display = l ? "block":"none";
	sCol('--tbp',l ? "14px 14px 10px 14px":"10px 22px 4px 22px");
	sCol('--bbp',l ? "9px 0 7px 0":"10px 0 4px 0");
	sCol('--bhd',l ? "block":"none");
	sCol('--bmt',l ? "0px":"5px");
	sCol('--t-b', cfg.theme.alpha.tab);
	size();
	localStorage.setItem('wledUiCfg', JSON.stringify(cfg));
}

function tglHex()
{
	cfg.comp.colors.hex = !cfg.comp.colors.hex;
	applyCfg();
}

function tglTheme()
{
	cfg.theme.base = (cfg.theme.base === "light") ? "dark":"light";
	applyCfg();
}

function tglLabels()
{
	cfg.comp.labels = !cfg.comp.labels;
	applyCfg();
}

function cTheme(light) {
	if (light) {
	sCol('--c-1','#eee');
	sCol('--c-f','#000');
	sCol('--c-2','#ddd');
	sCol('--c-3','#bbb');
	sCol('--c-4','#aaa');
	sCol('--c-5','#999');
	sCol('--c-6','#999');
	sCol('--c-8','#888');
	sCol('--c-b','#444');
	sCol('--c-c','#333');
	sCol('--c-e','#111');
	sCol('--c-d','#222');
	sCol('--c-r','#c42');
	sCol('--c-o','rgba(204, 204, 204, 0.9)');
	sCol('--c-sb','#0003'); sCol('--c-sbh','#0006');
	sCol('--c-tb','rgba(204, 204, 204, var(--t-b))');
	sCol('--c-tba','rgba(170, 170, 170, var(--t-b))');
	sCol('--c-tbh','rgba(204, 204, 204, var(--t-b))');
	d.getElementById('imgw').style.filter = "invert(0.8)";
	} else {
	sCol('--c-1','#111');
	sCol('--c-f','#fff');
	sCol('--c-2','#222');
	sCol('--c-3','#333');
	sCol('--c-4','#444');
	sCol('--c-5','#555');
	sCol('--c-6','#666');
	sCol('--c-8','#888');
	sCol('--c-b','#bbb');
	sCol('--c-c','#ccc');
	sCol('--c-e','#eee');
	sCol('--c-d','#ddd');
	sCol('--c-r','#831');
	sCol('--c-o','rgba(34, 34, 34, 0.9)');
	sCol('--c-sb','#fff3'); sCol('--c-sbh','#fff5');
	sCol('--c-tb','rgba(34, 34, 34, var(--t-b))');
	sCol('--c-tba','rgba(102, 102, 102, var(--t-b))');
	sCol('--c-tbh','rgba(51, 51, 51, var(--t-b))');
	d.getElementById('imgw').style.filter = "unset";
	}
}

function loadBg(iUrl) {
	let bg = document.getElementById('bg');
	let img = document.createElement("img");
	img.src = iUrl;
	img.addEventListener('load', (event) => {
		var a = parseFloat(cfg.theme.alpha.bg);
		d.getElementById('staytop2').style.background = "transparent";
		if (isNaN(a)) a = 0.6;
		bg.style.opacity = a;
		bg.style.backgroundImage = `url(${iUrl})`;
		img = null;
	});
}

function onLoad() {
	if (window.location.protocol == "file:") {
	loc = true;
	locip = localStorage.getItem('locIp');
	if (!locip)
	{
		locip = prompt("File Mode. Please enter WLED IP!");
		localStorage.setItem('locIp', locip);
	}
	}
	var sett = localStorage.getItem('wledUiCfg');
	if (sett) cfg = mergeDeep(cfg, JSON.parse(sett));
	
	resetPUtil();
	
	applyCfg();
	loadBg(cfg.theme.bg.url);
	
	var cd = d.getElementById('csl').children;
	for (i = 0; i < cd.length; i++) {
		cd[i].style.backgroundColor = "rgb(0, 0, 0)";
	}
	selectSlot(0);
	updateTablinks(0);
	resetUtil();
	cpick.on("input:end", function() {
		setColor(1);
	});
	pmtLS = localStorage.getItem('wledPmt');
	setTimeout(function(){requestJson(null, false)}, 25);
	d.addEventListener("visibilitychange", handleVisibilityChange, false);
	size();
	d.getElementById("cv").style.opacity=0;
	if (localStorage.getItem('pcm') == "true") togglePcMode(true);
	var sls = d.querySelectorAll('input[type="range"]');
	for (var sl of sls) {
		sl.addEventListener('input', updateBubble, true);
		sl.addEventListener('touchstart', toggleBubble);
		sl.addEventListener('touchend', toggleBubble);
	}

}

function updateTablinks(tabI)
{
	tablinks = d.getElementsByClassName("tablinks");
	for (i = 0; i < tablinks.length; i++) {
		tablinks[i].className = tablinks[i].className.replace(" active", "");
	}
	if (pcMode) return;
	tablinks[tabI].className += " active";
}

function openTab(tabI, force = false) {
	if (pcMode && !force) return;
	var i, tabcontent, tablinks;
	iSlide = tabI;
	_C.classList.toggle('smooth', false);
	_C.style.setProperty('--i', iSlide);
	updateTablinks(tabI);
}

var timeout;
function showToast(text, error = false) {
	if (error) d.getElementById('connind').style.backgroundColor = "#831";
	var x = d.getElementById("toast");
	x.innerHTML = text;
	x.className = error ? "error":"show";
	clearTimeout(timeout);
	x.style.animation = 'none';
	x.offsetHeight;
	x.style.animation = null; 
	timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900);
}

function showErrorToast() {
	showToast('Connection to light failed!', true);
}
function clearErrorToast() {
	d.getElementById("toast").className = d.getElementById("toast").className.replace("error", "");
}

function getRuntimeStr(rt)
{
	var t = parseInt(rt);
	var days = Math.floor(t/86400);
	var hrs = Math.floor((t - days*86400)/3600);
	var mins = Math.floor((t - days*86400 - hrs*3600)/60);
	var str = days ? (days + " " + (days == 1 ? "day" : "days") + ", ") : "";
	str += (hrs || days) ? (hrs + " " + (hrs == 1 ? "hour" : "hours")) : "";
	if (!days && hrs) str += ", ";
	if (t > 59 && !days) str += mins + " min";
	if (t < 3600 && t > 59) str += ", ";
	if (t < 3600) str += (t - mins*60) + " sec"; 
	return str;
}

function inforow(key, val, unit = "")
{
	return `<tr><td class="keytd">${key}</td><td class="valtd">${val}${unit}</td></tr>`;
}

function getLowestUnusedP()
{
	var l = 1;
	for (var key in pJson)
	{
		if (key == l) l++;
  }
  if (l > 250) l = 250; 
	return l;
}

function checkUsed(i) {
	var id = d.getElementById(`p${i}id`).value;
	if (pJson[id] && (i == 0 || id != i)) {
		d.getElementById(`p${i}warn`).innerHTML = `&#9888; Overwriting ${pName(id)}!`
	} else {
		d.getElementById(`p${i}warn`).innerHTML = "";
	}
}

function pName(i) {
	var n = "Preset " + i;
	if (pJson[i].n) n = pJson[i].n;
	return n;
}

function papiVal(i) {
	if (!pJson[i]) return "";
	var o = Object.assign({},pJson[i]);
	if (o.win) return o.win;
	delete o.n; delete o.p; delete o.ql;
	return JSON.stringify(o);
}

function qlName(i) {
	if (!pJson[i]) return "";
  if (!pJson[i].ql) return "";
  return pJson[i].ql;
}

function cpBck() {
	var copyText = document.getElementById("bck");

  copyText.select();
  copyText.setSelectionRange(0, 999999);

  document.execCommand("copy");
	
	showToast("Copied to clipboard!")
}

function presetError(empty)
{
	var hasBackup = false; var bckstr = "";
	try {
		bckstr = localStorage.getItem("wledP");
		if (bckstr.length > 10) hasBackup = true;
	} catch (e) {
	
	}
	var cn = `<div class="seg c">`;
	if (empty) 
		cn += `You have no presets yet!`;
	else 
		cn += `Sorry, there was an issue loading your presets!`;

	if (hasBackup) {
		cn += `<br><br>`;
		if (empty)
			cn += `However, there is backup preset data of a previous installation available.<br>
			(Saving a preset will hide this and overwrite the backup)`;
		else
			cn += `Here is a backup of the last known good state:`;
		cn += `<textarea id="bck"></textarea><br>
			<button class="btn btn-p" onclick="cpBck()">Copy to clipboard</button>`
	}
	cn += `</div>`;
	d.getElementById('pcont').innerHTML = cn;
	if (hasBackup) d.getElementById('bck').value = bckstr;
}

function loadPresets()
{
	var url = '/presets.json';
	if (loc) {
		url = `http://${locip}/presets.json`;
	}
	
	fetch
	(url, {
		method: 'get'
	})
	.then(res => {
		if (!res.ok) {
			 showErrorToast();
		}
		return res.json();
	})
	.then(json => {
		pJson = json;
		populatePresets();
	})
	.catch(function (error) {
		showToast(error, true);
		console.log(error);
		presetError(false);
	})
}

var pQL = [];

function populateQL()
{
	var cn = "";
	if (pQL.length > 0) {
	cn += `<p class="labels">Quick load</p>`;
  
  var it = 0;
	for (var key in pQL)
	{
    cn += `<button class="xxs btn psts" id="p${pQL[key][0]}qlb" onclick="setPreset(${pQL[key][0]});">${pQL[key][1]}</button>`;
    it++;
    if (it > 4) {
      it = 0;
      cn += '<br>';
    }
  }
  if (it != 0) cn+= '<br>';
	
	cn += `<p class="labels">All presets</p>`;
	}
	d.getElementById('pql').innerHTML = cn;
}

function populatePresets(fromls)
{
	if (fromls) pJson = JSON.parse(localStorage.getItem("wledP"));
	delete pJson["0"];
	var cn = "";
	var arr = Object.entries(pJson);
	arr.sort(cmpP);
	var added = false;
  pQL = [];
  var is = [];

	for (var key in arr)
	{
		if (!isObject(arr[key][1])) continue;
		var i = parseInt(arr[key][0]);
		var qll = arr[key][1]["ql"];
    if (qll) pQL.push([i, qll]);
    is.push(i);
		
		cn += `<div class="seg pres" id="p${i}o">
			<div class="segname pname" onclick="setPreset(${i})">
				${pName(i)}
			</div>
			<i class="icons e-icon flr ${expanded[i+100] ? "exp":""}" id="sege${i+100}" onclick="expand(${i+100})">&#xe395;</i>
			<div class="segin" id="seg${i+100}"></div>
		</div><br>`;
		added = true;
	}

	d.getElementById('pcont').innerHTML = cn;
	if (added) {
		if (pmtLS != pmt && pmt != 0) {
			localStorage.setItem("wledPmt", pmt);
			pJson["0"] = {};
			localStorage.setItem("wledP", JSON.stringify(pJson));
		}
    pmtLS = pmt;
    for (var a in is) {
      var i = is[a];
      if (expanded[i+100]) expand(i+100, true);
    }
	} else { presetError(true); }
	updatePA();
	populateQL();
}

function populateInfo(i)
{
	var cn="";
	var heap = i.freeheap/1000;
	heap = heap.toFixed(1);
	var pwr = i.leds.pwr;
	var pwru = "Not calculated";
	if (pwr > 1000) {pwr /= 1000; pwr = pwr.toFixed((pwr > 10) ? 0 : 1); pwru = pwr + " A";}
	else if (pwr > 0) {pwr = 50 * Math.round(pwr/50); pwru = pwr + " mA";}
	var urows="";
	for (var k in i.u)
	{
		var val = i.u[k];
		if (val[1]) {
			urows += inforow(k,val[0],val[1]);
		} else {
			urows += inforow(k,val);
		}
	}
	var vcn = "Kuuhaku";
	if (i.ver.startsWith("0.11.")) vcn = "Mirai";
	if (i.cn) vcn = i.cn;
	
	cn += `v${i.ver} "${vcn}"<br><br><table class="infot">
	${urows}
	${inforow("Build",i.vid)}
	${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")}
	${inforow("Uptime",getRuntimeStr(i.uptime))}
	${inforow("Free heap",heap," kB")}
	${inforow("Estimated current",pwru)}
	${inforow("MAC address",i.mac)}
	${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")}
	${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")}
	</table>`;
	d.getElementById('kv').innerHTML = cn;
}

function populateSegments(s)
{
	var cn = "";
	segCount = 0, lowestUnused = 0; lSeg = 0;
 
	for (y in s.seg)
	{
		segCount++;
		
		var inst=s.seg[y];
		var i = parseInt(inst.id);
		powered[i] = inst.on;
		if (i == lowestUnused) lowestUnused = i+1;
		if (i > lSeg) lSeg = i;
		
		cn += `<div class="seg">
			<label class="check schkl">
				&nbsp;
				<input type="checkbox" id="seg${i}sel" onchange="selSeg(${i})" ${inst.sel ? "checked":""}>
				<span class="checkmark schk"></span>
			</label>
			<div class="segname" onclick="selSegEx(${i})">
				Segment ${i}
			</div>
			<i class="icons e-icon flr ${expanded[i] ? "exp":""}" id="sege${i}" onclick="expand(${i})">&#xe395;</i>
			<div class="segin ${expanded[i] ? "expanded":""}" id="seg${i}">
			<table class="segt">
				<tr>
					<td class="segtd">Start LED</td>
					<td class="segtd">Stop LED</td>
				</tr>
				<tr>
					<td class="segtd"><input class="noslide segn" id="seg${i}s" type="number" min="0" max="${ledCount-1}" value="${inst.start}" oninput="updateLen(${i})"></td>
					<td class="segtd"><input class="noslide segn" id="seg${i}e" type="number" min="0" max="${ledCount}" value="${inst.stop}" oninput="updateLen(${i})"></td>
				</tr>
			</table>
			<table class="segt">
				<tr>
					<td class="segtd">Grouping</td>
					<td class="segtd">Spacing</td>
				</tr>
				<tr>
					<td class="segtd"><input class="noslide segn" id="seg${i}grp" type="number" min="1" max="255" value="${inst.grp}" oninput="updateLen(${i})"></td>
					<td class="segtd"><input class="noslide segn" id="seg${i}spc" type="number" min="0" max="255" value="${inst.spc}" oninput="updateLen(${i})"></td>
				</tr>
			</table>
			<div class="h bp" id="seg${i}len"></div>
			<i class="icons e-icon pwr ${powered[i] ? "act":""}" id="seg${i}pwr" onclick="setSegPwr(${i})">&#xe08f;</i>
			<div class="sliderwrap il sws">
				<input id="seg${i}bri" class="noslide sis" onchange="setSegBri(${i})" oninput="updateTrail(this)" max="255" min="1" type="range" value="${inst.bri}" />
				<div class="sliderdisplay"></div>
			</div>
				<i class="icons e-icon cnf cnf-s" id="segc${i}" onclick="setSeg(${i})">&#xe390;</i>
				<i class="icons e-icon del" id="segd${i}" onclick="delSeg(${i})">&#xe037;</i>
				<label class="check revchkl">
					Reverse direction
					<input type="checkbox" id="seg${i}rev" onchange="setRev(${i})" ${inst.rev ? "checked":""}>
					<span class="checkmark schk"></span>
				</label>
				<label class="check revchkl">
					Mirror effect
					<input type="checkbox" id="seg${i}mi" onchange="setMi(${i})" ${inst.mi ? "checked":""}>
					<span class="checkmark schk"></span>
				</label>
			</div>
		</div><br>`;
	}

	d.getElementById('segcont').innerHTML = cn;
	if (lowestUnused >= maxSeg) {
		d.getElementById('segutil').innerHTML = '<span class="h">Maximum number of segments reached.</span>';
		noNewSegs = true;
	} else if (noNewSegs) {
		resetUtil();
		noNewSegs = false;
	}
	for (i = 0; i <= lSeg; i++) {
	updateLen(i);
	updateTrail(d.getElementById(`seg${i}bri`));
	if (segCount < 2) d.getElementById(`segd${lSeg}`).style.display = "none";
	}
	d.getElementById('rsbtn').style.display = (segCount > 1) ? "inline":"none";
}

function updateTrail(e, slidercol)
{
	if (e==null) return;
	var max = e.hasAttribute('max') ? e.attributes['max'].value : 255;
	var progress = e.value * 100 / max;
	progress = parseInt(progress);
	var scol;
	switch (slidercol) {
	case 1: scol = "#f00"; break;
	case 2: scol = "#0f0"; break;
	case 3: scol = "#00f"; break;
	default: scol = "var(--c-f)";
	}
	var val = `linear-gradient(90deg, ${scol} ${progress}%, var(--c-4) ${progress}%)`;
	e.parentNode.getElementsByClassName('sliderdisplay')[0].style.background = val;
}

function updateBubble(e)
{
	var bubble = e.target.parentNode.getElementsByTagName('output')[0]
	var max = e.target.hasAttribute('max') ? e.target.attributes.max.value : 255;

	if (bubble) {
		bubble.innerHTML = e.target.value
	}
}

function toggleBubble(e)
{
	e.target.parentNode.querySelector('output').classList.toggle('hidden');
}

function updateLen(s)
{
	if (!d.getElementById(`seg${s}s`)) return;
	var start = parseInt(d.getElementById(`seg${s}s`).value);
	var stop	= parseInt(d.getElementById(`seg${s}e`).value);
	var len = stop - start;
	var out = "(delete)"
	if (len > 1) {
		out = `${len} LEDs`;
	} else if (len == 1) {
		out = "1 LED"
	}
	
	if (d.getElementById(`seg${s}grp`) != null)
	{
		var grp = parseInt(d.getElementById(`seg${s}grp`).value);
		var spc = parseInt(d.getElementById(`seg${s}spc`).value);
		if (grp == 0) grp = 1;
		var virt = Math.ceil(len/(grp + spc));
		if (!isNaN(virt) && (grp > 1 || spc > 0)) out += ` (${virt} virtual)`;
	}
	
	d.getElementById(`seg${s}len`).innerHTML = out;
}

function updatePA()
{
	var ps = d.getElementsByClassName("seg");
	for (i = 0; i < ps.length; i++) {
		ps[i].style.backgroundColor = "var(--c-2)";
	}
	ps = d.getElementsByClassName("psts");
	for (i = 0; i < ps.length; i++) {
		ps[i].style.backgroundColor = "var(--c-2)";
	}
	if (currentPreset > 0) {
		var acv = d.getElementById(`p${currentPreset}o`);
		if (acv && !expanded[currentPreset+100])
			acv.style.background = "var(--c-6)";
		acv = d.getElementById(`p${currentPreset}qlb`);
		if (acv) acv.style.background = "var(--c-6)";
	}
}

function updateUI()
{
	d.getElementById('buttonPower').className = (isOn) ? "active":"";
	d.getElementById('buttonNl').className = (nlA) ? "active":"";
	d.getElementById('buttonSync').className = (syncSend) ? "active":"";

	d.getElementById('fxb' + selectedFx).style.backgroundColor = "var(--c-6)";
	updateTrail(d.getElementById('sliderBri'));
	updateTrail(d.getElementById('sliderSpeed'));
	updateTrail(d.getElementById('sliderIntensity'));
	updateTrail(d.getElementById('sliderW'));
	if (isRgbw) d.getElementById('wwrap').style.display = "block";

	spal = d.getElementById("selectPalette");
	spal.style.backgroundColor = (spal.selectedIndex > 0) ? "var(--c-6)":"var(--c-3)";
	updatePA();
	updateHex();
	updateRgb();
}

function displayRover(i,s)
{
	d.getElementById('rover').style.transform = (i.live && s.lor == 0) ? "translateY(0px)":"translateY(100%)";
	var sour = i.lip ? i.lip:""; if (sour.length > 2) sour = " from " + sour;
	d.getElementById('lv').innerHTML = `WLED is receiving live ${i.lm} data${sour}`;
	d.getElementById('roverstar').style.display = (i.live && s.lor) ? "block":"none";
}

function compare(a, b) {
	if (a.name < b.name) return -1;
	return 1;
}
function cmpP(a, b) {
	if (!a[1].n) return (a[0] > b[0]);
  return a[1].n.localeCompare(b[1].n,undefined, {numeric: true});
}

var jsonTimeout;
var reqC = 0;
function requestJson(command, rinfo = true, verbose = true) {
	d.getElementById('connind').style.backgroundColor = "#a90";
	lastUpdate = new Date();
	if (!jsonTimeout) jsonTimeout = setTimeout(showErrorToast, 3000);
	var req = null;
	e1 = d.getElementById('fxlist');
	e2 = d.getElementById('selectPalette');

	url = rinfo ? '/json/si': (command ? '/json/state':'/json');
	if (loc) {
		url = `http://${locip}${url}`;
	}
	
	type = command ? 'post':'get';
	if (command)
	{
    command.v = verbose;
    command.time = Math.floor(Date.now() / 1000);
		req = JSON.stringify(command);
		//console.log(req);
	}
	fetch
	(url, {
		method: type,
		headers: {
			"Content-type": "application/json; charset=UTF-8"
		},
		body: req
	})
	.then(res => {
		if (!res.ok) {
			 showErrorToast();
		}
		return res.json();
	})
	.then(json => {
		clearTimeout(jsonTimeout);
		jsonTimeout = null;
		clearErrorToast();
		d.getElementById('connind').style.backgroundColor = "#070";
		if (!json) showToast('Empty response', true);
		if (json.success) return;
		var s = json;
		if (!command || rinfo) {
		if (!rinfo) {
		pmt = json.info.fs.pmt;
    if (pmt != pmtLS || pmt == 0) {
      setTimeout(loadPresets,99);
    }
    else populatePresets(true);
    pmtLast = pmt;
		var x='',y='<option value="0">Default</option>';
		json.effects.shift(); //remove solid
		for (i in json.effects) json.effects[i] = {id: parseInt(i)+1, name:json.effects[i]};
		json.effects.sort(compare);
		for (i in json.effects) {
		x += `<button class="btn${(i==0)?" first":""}" id="fxb${json.effects[i].id}" onclick="setX(${json.effects[i].id});">${json.effects[i].name}</button><br>`;
		}

		json.palettes.shift(); //remove default
		for (i in json.palettes) json.palettes[i] = {"id": parseInt(i)+1, "name":json.palettes[i]};
		json.palettes.sort(compare);
		for (i in json.palettes) {
		y += `<option value="${json.palettes[i].id}">${json.palettes[i].name}</option>`;
		}
		e1.innerHTML=x; e2.innerHTML=y;
		}
		
			var info = json.info;
			var name = info.name;
			d.getElementById('namelabel').innerHTML = name;
			if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)";
			if (info.live) name = "(Live) " + name;
		if (loc) name = "(L) " + name;
			d.title = name;
			isRgbw = info.leds.wv;
			ledCount = info.leds.count;
			syncTglRecv = info.str;
      maxSeg = info.leds.maxseg;
      pmt = info.fs.pmt;
      if (!command && pmt != pmtLast) setTimeout(loadPresets,99);
      pmtLast = pmt;
		lastinfo = info;
		if (isInfo) populateInfo(info);
			s = json.state;
			displayRover(info, s);
		}
		isOn = s.on;
		d.getElementById('sliderBri').value= s.bri;
		nlA = s.nl.on;
		nlDur = s.nl.dur;
		nlTar = s.nl.tbri;
		nlFade = s.nl.fade;
		syncSend = s.udpn.send;
		savedPresets = s.pss;
		currentPreset = s.ps;
		d.getElementById('cyToggle').checked = (s.pl < 0) ? false : true;
		d.getElementById('cycs').value = s.ccnf.min;
		d.getElementById('cyce').value = s.ccnf.max;
		d.getElementById('cyct').value = s.ccnf.time /10;
		d.getElementById('cyctt').value = s.transition /10;
		
		var selc=0; var ind=0;
		populateSegments(s);
		for (i in s.seg)
		{
			if(s.seg[i].sel) {selc = ind; break;} ind++;
		}
		var i=s.seg[selc];
		if (!i) {
			showToast('No Segments!', true);
			updateUI();
			return;
		}
		var cd = d.getElementById('csl').children;
		for (e = 2; e >= 0; e--)
		{
			cd[e].style.backgroundColor = "rgb(" + i.col[e][0] + "," + i.col[e][1] + "," + i.col[e][2] + ")";
			if (isRgbw) whites[e] = parseInt(i.col[e][3]);
			selectSlot(csel);
		}
		d.getElementById('sliderSpeed').value = whites[csel];

		d.getElementById('sliderSpeed').value = i.sx;
		d.getElementById('sliderIntensity').value = i.ix;

		d.getElementById('fxb' + selectedFx).style.backgroundColor = "var(--c-3)";
		selectedFx = i.fx;
		e2.value = i.pal;
		if (!command) d.getElementById('Effects').scrollTop = d.getElementById('fxb' + selectedFx).offsetTop - d.getElementById('Effects').clientHeight/1.8;

		if (s.error && s.error != 0) {
      var errstr = "";
      switch (s.error) {
        case 10: errstr = "Could not mount filesystem!"; break;
        case 11: errstr = "Not enough space to save preset!"; break;
        case 12: errstr = "The requested preset does not exist."; break;
        case 19: errstr = "A filesystem error has occured."; break;
      }
      showToast('Error ' + s.error + ": " + errstr, true);
    }
		updateUI();
	})
	.catch(function (error) {
		showToast(error, true);
	  console.log(error);
	})
}

function togglePower() {
	isOn = !isOn;
	var obj = {"on": isOn};
	obj.transition = parseInt(d.getElementById('cyctt').value*10);
	requestJson(obj);
}

function toggleNl() {
	nlA = !nlA;
	if (nlA)
	{
		showToast(`Timer active. Your light will turn ${nlTar > 0 ? "on":"off"} ${nlFade ? "over":"after"} ${nlDur} minutes.`);
	} else {
		showToast('Timer deactivated.');
	}
	var obj = {"nl": {"on": nlA}};
	requestJson(obj);
}

function toggleSync() {
	syncSend = !syncSend;
	if (syncSend)
	{
		showToast('Other lights in the network will now sync to this one.');
	} else {
		showToast('This light and other lights in the network will no longer sync.');
	}
	var obj = {"udpn": {"send": syncSend}};
	if (syncTglRecv) obj.udpn.recv = syncSend;
	requestJson(obj);
}

function toggleLiveview() {
	isLv = !isLv;
	d.getElementById('liveview').style.display = (isLv) ? "block":"none";
	var url = loc ? `http://${locip}/liveview`:"/liveview";
	d.getElementById('liveview').src = (isLv) ? url:"about:blank";
	d.getElementById('buttonSr').className = (isLv) ? "active":"";
	size();
}

function toggleInfo() {
	isInfo = !isInfo;
	if (isInfo) populateInfo(lastinfo);
	d.getElementById('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)";
	d.getElementById('buttonI').className = (isInfo) ? "active":"";
}

function makeSeg() {
	var ns = 0;
	if (lowestUnused > 0) {
		var pend = d.getElementById(`seg${lowestUnused -1}e`).value;
		if (pend < ledCount) ns = pend;
	}
	var cn = `<div class="seg">
			<div class="segname newseg">
				New segment ${lowestUnused}
			</div>
			<br>
			<div class="segin expanded">
				<table class="segt">
					<tr>
						<td class="segtd">Start LED</td>
						<td class="segtd">Stop LED</td>
					</tr>
					<tr>
						<td class="segtd"><input class="noslide segn" id="seg${lowestUnused}s" type="number" min="0" max="${ledCount-1}" value="${ns}" oninput="updateLen(${lowestUnused})"></td>
						<td class="segtd"><input class="noslide segn" id="seg${lowestUnused}e" type="number" min="0" max="${ledCount}" value="${ledCount}" oninput="updateLen(${lowestUnused})"></td>
					</tr>
				</table>
				<div class="h" id="seg${lowestUnused}len">${ledCount - ns} LEDs</div>
				<i class="icons e-icon cnf cnf-s half" id="segc${lowestUnused}" onclick="setSeg(${lowestUnused}); resetUtil();">&#xe390;</i>
			</div>
		</div>`;
	d.getElementById('segutil').innerHTML = cn;
}

function resetUtil() {
	var cn = `<button class="btn btn-s btn-i" onclick="makeSeg()"><i class="icons btn-icon">&#xe18a;</i>Add segment</button><br>`;
	d.getElementById('segutil').innerHTML = cn;
}

function makeP(i) {
	return `
	<input type="text" class="ptxt noslide" id="p${i}txt" autocomplete="off" maxlength=32 value="${(i>0)?pName(i):""}" placeholder="Enter name..."/><br>
	<div class="c">Quick load label: <input type="text" class="stxt noslide" maxlength=2 value="${qlName(i)}" id="p${i}ql" autocomplete="off"/></div>
	<div class="h">(leave empty for no Quick load button)</div>
	<label class="check revchkl">
		${(i>0)?"Overwrite with state":"Use current state"}
		<input type="checkbox" id="p${i}cstgl" onchange="tglCs(${i})" ${(i>0)?"":"checked"}>
		<span class="checkmark schk"></span>
	</label><br>
	<div class="po2" id="p${i}o2">
		API command<br>
		<textarea class="noslide" id="p${i}api"></textarea>
	</div>
	<div class="po1" id="p${i}o1">
		<label class="check revchkl">
			Include brightness
			<input type="checkbox" id="p${i}ibtgl" checked>
			<span class="checkmark schk"></span>
		</label>
		<label class="check revchkl">
			Save segment bounds
			<input type="checkbox" id="p${i}sbtgl" checked>
			<span class="checkmark schk"></span>
		</label>
	</div>
	<div class="c">Save to ID <input class="noslide" id="p${i}id" type="number" oninput="checkUsed(${i})" max=250 min=1 value=${(i>0)?i:getLowestUnusedP()}></div>
	<div class="c">
		<button class="btn btn-i btn-p" onclick="saveP(${i})"><i class="icons btn-icon">&#xe390;</i>${(i>0)?"Save changes":"Save preset"}</button>
		${(i>0)?'<button class="btn btn-i btn-p" onclick="delP('+i+')"><i class="icons btn-icon">&#xe037;</i>Delete preset</button>':
						'<button class="btn btn-p" onclick="resetPUtil()">Cancel</button>'}
	</div>
	<div class="pwarn ${(i>0)?"bp":""} c" id="p${i}warn">

	</div>
	${(i>0)? ('<div class="h">ID ' +i+ '</div>'):""}`;
}

function makePUtil() {
	d.getElementById('putil').innerHTML = `<div class="seg pres">
		<div class="segname newseg">
			New preset</div>
		<div class="segin expanded">
		${makeP(0)}</div></div>`;
	updateTrail(d.getElementById('p0p'));
}

function resetPUtil() {
	var cn = `<button class="btn btn-s btn-i" onclick="makePUtil()"><i class="icons btn-icon">&#xe18a;</i>Create preset</button><br>`;
	d.getElementById('putil').innerHTML = cn;
}

function tglCs(i){
	var pss = d.getElementById(`p${i}cstgl`).checked;
	d.getElementById(`p${i}o1`).style.display = pss? "block" : "none";
	d.getElementById(`p${i}o2`).style.display = !pss? "block" : "none";
}

function selSegEx(s)
{
	var obj = {"seg":[]};
	for(i=0; i<=lSeg; i++){
		obj.seg.push({"sel":(i==s)?true:false});
	}
	requestJson(obj);
}

function selSeg(s){
	var sel = d.getElementById(`seg${s}sel`).checked;
	var obj = {"seg": {"id": s, "sel": sel}};
	requestJson(obj, false);
}

function setSeg(s){
	var start = parseInt(d.getElementById(`seg${s}s`).value);
	var stop	= parseInt(d.getElementById(`seg${s}e`).value);
	if (stop <= start) {delSeg(s); return;};
	var obj = {"seg": {"id": s, "start": start, "stop": stop}};
	if (d.getElementById(`seg${s}grp`))
	{
		var grp = parseInt(d.getElementById(`seg${s}grp`).value);
		var spc = parseInt(d.getElementById(`seg${s}spc`).value);
		obj.seg.grp = grp;
		obj.seg.spc = spc;
	}
	requestJson(obj);
}

function delSeg(s){
	if (segCount < 2) {
		showToast("You need to have multiple segments to delete one!");
		return;
	}
	expanded[s] = false;
	segCount--;
	var obj = {"seg": {"id": s, "stop": 0}};
	requestJson(obj, false);
}

function setRev(s){
	var rev = d.getElementById(`seg${s}rev`).checked;
	var obj = {"seg": {"id": s, "rev": rev}};
	requestJson(obj, false);
}

function setMi(s){
	var mi = d.getElementById(`seg${s}mi`).checked;
	var obj = {"seg": {"id": s, "mi": mi}};
	requestJson(obj, false);
}

function setSegPwr(s){
	var obj = {"seg": {"id": s, "on": !powered[s]}};
	requestJson(obj);
}

function setSegBri(s){
	var obj = {"seg": {"id": s, "bri": parseInt(d.getElementById(`seg${s}bri`).value)}};
	requestJson(obj);
}

function setX(ind) {
	var obj = {"seg": {"fx": parseInt(ind)}};
	requestJson(obj);
}

function setPalette()
{
	var obj = {"seg": {"pal": parseInt(d.getElementById('selectPalette').value)}};
	requestJson(obj);
}

function setBri() {
	var obj = {"bri": parseInt(d.getElementById('sliderBri').value)};
	obj.transition = parseInt(d.getElementById('cyctt').value*10);
	requestJson(obj);
}

function setSpeed() {
	var obj = {"seg": {"sx": parseInt(d.getElementById('sliderSpeed').value)}};
	requestJson(obj, false);
}

function setIntensity() {
	var obj = {"seg": {"ix": parseInt(d.getElementById('sliderIntensity').value)}};
	requestJson(obj, false);
}

function setLor(i) {
	var obj = {"lor": i};
	requestJson(obj);
}

function toggleCY() {
	var obj = {"pl" : -1};
	if (d.getElementById('cyToggle').checked)
	{
		obj = {"pl": 0, "ccnf": {"min": parseInt(d.getElementById('cycs').value), "max": parseInt(d.getElementById('cyce').value), "time": parseInt(d.getElementById('cyct').value*10)}};
		obj.transition = parseInt(d.getElementById('cyctt').value*10);
	}
	
	requestJson(obj);
}

function setPreset(i) {
	var obj = {"ps": i}

	showToast("Loading preset " + pName(i) +" (" + i + ")");

	requestJson(obj);
}

function saveP(i) {
	pI = parseInt(d.getElementById(`p${i}id`).value);
	if (!pI || pI < 1) pI = (i>0) ? i : getLowestUnusedP();
	pN = d.getElementById(`p${i}txt`).value;
	if (pN == "") pN = "Preset " + pI;
	var obj = {};
	if (!d.getElementById(`p${i}cstgl`).checked) {
		var raw = d.getElementById(`p${i}api`).value;
		try {
			obj = JSON.parse(raw);
		} catch (e) {
			obj["win"] = raw;
			if (raw.length < 2) {
				d.getElementById(`p${i}warn`).innerHTML = "&#9888; Please enter your API command first";
				return;
			} else if (raw.indexOf('{') > -1) {
				d.getElementById(`p${i}warn`).innerHTML = "&#9888; Syntax error in custom JSON API command";
				return;
			} else if (raw.indexOf("Please") == 0) {
        d.getElementById(`p${i}warn`).innerHTML = "&#9888; Please refresh the page before modifying this preset";
				return;
      }
		}
		obj["o"] = true;
	} else {
		obj["ib"] = d.getElementById(`p${i}ibtgl`).checked;
		obj["sb"] = d.getElementById(`p${i}sbtgl`).checked;
	}
	obj["psave"] = pI; obj["n"] = pN;
	var pQN = d.getElementById(`p${i}ql`).value;
	if (pQN.length > 0) obj["ql"] = pQN;

  showToast("Saving " + pN +" (" + pI + ")");
	requestJson(obj);
	if (obj["o"]) {
		pJson[pI] = obj;
    delete pJson[pI]["psave"];
    delete pJson[pI]["o"];
    delete pJson[pI]["v"];
    delete pJson[pI]["time"];
	} else {
		pJson[pI] = {"n":pN, "win":"Please refresh the page to see this newly saved command."};
		if (obj["win"]) pJson[pI]["win"] = obj["win"];
		if (obj["ql"])  pJson[pI]["ql"] = obj["ql"];
	}
	populatePresets();
	resetPUtil();
}

function delP(i) {
	var obj = {"pdel": i};
	requestJson(obj);
	delete pJson[i];
	populatePresets();
}

function selectSlot(b) {
	csel = b;
	var cd = d.getElementById('csl').children;
	for (i = 0; i < cd.length; i++) {
		cd[i].style.border="2px solid white";
		cd[i].style.margin="5px";
		cd[i].style.width="42px";
	}
	cd[csel].style.border="5px solid white";
	cd[csel].style.margin="2px";
	cd[csel].style.width="50px";
	cpick.color.set(cd[csel].style.backgroundColor);
	d.getElementById('sliderW').value = whites[csel];
	updateTrail(d.getElementById('sliderW'));
	updateHex();
	updateRgb();
}

var lasth = 0;
function pC(col)
{
	if (col == "rnd")
	{
	col = {h: 0, s: 0, v: 100};
	col.s = Math.floor((Math.random() * 50) + 50);
	do {
		col.h = Math.floor(Math.random() * 360);
	} while (Math.abs(col.h - lasth) < 50);
	lasth = col.h;
	}
	cpick.color.set(col);
	setColor(0);
}

function updateRgb()
{
	var col = cpick.color.rgb;
	var s = d.getElementById('sliderR');
	s.value = col.r; updateTrail(s,1);
	s = d.getElementById('sliderG');
	s.value = col.g; updateTrail(s,2);
	s = d.getElementById('sliderB');
	s.value = col.b; updateTrail(s,3);
}

function updateHex()
{
	var str = cpick.color.hexString;
	str = str.substring(1);
	var w = whites[csel];
	if (w > 0) str += w.toString(16);
	d.getElementById('hexc').value = str;
	d.getElementById('hexcnf').style.backgroundColor = "var(--c-3)";
}

function hexEnter() {
	d.getElementById('hexcnf').style.backgroundColor = "var(--c-6)";
	if(event.keyCode == 13) fromHex();
}

function fromHex()
{
	var str = d.getElementById('hexc').value;
	whites[csel] = parseInt(str.substring(6), 16);
	try {
		cpick.color.set("#" + str.substring(0,6));
	} catch (e) {
		cpick.color.set("#ffaa00");
	}
	if (isNaN(whites[csel])) whites[csel] = 0;
	setColor(2);
}

function fromRgb()
{
	var r = d.getElementById('sliderR').value;
	var g = d.getElementById('sliderG').value;
	var b = d.getElementById('sliderB').value;
	cpick.color.set(`rgb(${r},${g},${b})`);
	setColor(0);
}

function setColor(sr) {
	var cd = d.getElementById('csl').children;
	if (sr == 1 && cd[csel].style.backgroundColor == 'rgb(0, 0, 0)') cpick.color.setChannel('hsv', 'v', 100);
	cd[csel].style.backgroundColor = cpick.color.rgbString;
	if (sr != 2) whites[csel] = d.getElementById('sliderW').value;
	var col = cpick.color.rgb;
	var obj = {"seg": {"col": [[col.r, col.g, col.b, whites[csel]],[],[]]}};
	if (csel == 1) {
		obj = {"seg": {"col": [[],[col.r, col.g, col.b, whites[csel]],[]]}};
	} else if (csel == 2) {
		obj = {"seg": {"col": [[],[],[col.r, col.g, col.b, whites[csel]]]}};
	}
	updateHex();
	updateRgb();
	obj.transition = parseInt(d.getElementById('cyctt').value*10);
	requestJson(obj);
}

var hc = 0;
setInterval(function(){if (!isInfo) return; hc+=18; if (hc>300) hc=0; if (hc>200)hc=306; if (hc==144) hc+=36; if (hc==108) hc+=18;
d.getElementById('heart').style.color = `hsl(${hc}, 100%, 50%)`}, 910);

function openGH()
{
	window.open("https://github.com/Aircoookie/WLED/wiki");
}

var cnfr = false;
function cnfReset()
{
	if (!cnfr)
	{
		var bt = d.getElementById('resetbtn');
	bt.style.color = "#f00";
	bt.innerHTML = "Confirm Reboot";
	cnfr = true; return;
	}
	window.location.href = "/reset";
}

var cnfrS = false;
function rSegs()
{
	var bt = d.getElementById('rsbtn');
	if (!cnfrS)
	{
	bt.style.color = "#f00";
	bt.innerHTML = "Confirm reset";
	cnfrS = true; return;
	}
	cnfrS = false;
	bt.style.color = "#fff";
	bt.innerHTML = "Reset segments";
	var obj = {"seg":[{"start":0,"stop":ledCount,"sel":true}]};
	for(i=1; i<=lSeg; i++){
		obj.seg.push({"stop":0});
	}
	requestJson(obj);
}

function expand(i,a)
{
	if (!a) expanded[i] = !expanded[i];
	d.getElementById('seg' +i).style.display = (expanded[i]) ? "block":"none";
	d.getElementById('sege' +i).style.transform = (expanded[i]) ? "rotate(180deg)":"rotate(0deg)"
	if (i > 100) { //presets
		var p = i-100;
		d.getElementById(`p${p}o`).style.background = (expanded[i] || p != currentPreset)?"var(--c-2)":"var(--c-6)";
		if (d.getElementById('seg' +i).innerHTML == "") {
      d.getElementById('seg' +i).innerHTML = makeP(p);
      var papi = papiVal(p);
      d.getElementById(`p${p}api`).value = papi;
      if (papi.indexOf("Please") == 0) d.getElementById(`p${p}cstgl`).checked = true;
      tglCs(p);
		}
	}
}

function unfocusSliders() {
	d.getElementById("sliderBri").blur();
	d.getElementById("sliderSpeed").blur();
	d.getElementById("sliderIntensity").blur();
}

//sliding UI
const _C = document.querySelector('.container'), N = 4;

let iSlide = 0, x0 = null, scrollS = 0, locked = false, w;

function unify(e) {	return e.changedTouches ? e.changedTouches[0] : e }

function lock(e) {
	if (pcMode) return;
	var l = e.target.classList;
	if (l.contains('noslide') || l.contains('iro__wheel__saturation') || l.contains('iro__slider__value')	|| l.contains('iro__slider')) return;
	x0 = unify(e).clientX;
	scrollS = d.getElementsByClassName("tabcontent")[iSlide].scrollTop;

	_C.classList.toggle('smooth', !(locked = true))
}

function move(e) {
	if(!locked || pcMode) return;
	var dx = unify(e).clientX - x0, s = Math.sign(dx), 
			f = +(s*dx/w).toFixed(2);

  if((iSlide > 0 || s < 0) && (iSlide < N - 1 || s > 0)
     && f > .12
     && d.getElementsByClassName("tabcontent")[iSlide].scrollTop == scrollS) {
		_C.style.setProperty('--i', iSlide -= s);
		f = 1 - f;
		updateTablinks(iSlide);
	}
	_C.style.setProperty('--f', f);
	_C.classList.toggle('smooth', !(locked = false));
	x0 = null
}

function size() { 
	w = window.innerWidth;
	var h = d.getElementById('top').clientHeight;
	sCol('--th', h + "px");
	sCol('--bh', d.getElementById('bot').clientHeight + "px");
	if (isLv) h -= 4;
	sCol('--tp', h + "px");
	togglePcMode();
}

function togglePcMode(fromB = false)
{
	if (fromB) {
	pcModeA = !pcModeA;
	localStorage.setItem('pcm', pcModeA);
	pcMode = pcModeA;
	}
	if (w < 1250 && !pcMode) return;
	if (!fromB && ((w < 1250 && lastw < 1250) || (w >= 1250 && lastw >= 1250))) return;
	openTab(0, true);
	if (w < 1250) {pcMode = false;}
	else if (pcModeA && !fromB) pcMode = pcModeA;
	updateTablinks(0);
	d.getElementById('buttonPcm').className = (pcMode) ? "active":"";
	d.getElementById('bot').style.height = (pcMode && !cfg.comp.pcmbot) ? "0":"auto";
	sCol('--bh', d.getElementById('bot').clientHeight + "px");
  _C.style.width = (pcMode)?'100%':'400%';
	lastw = w;
}

function isObject(item) {
	return (item && typeof item === 'object' && !Array.isArray(item));
}

function mergeDeep(target, ...sources) {
	if (!sources.length) return target;
	const source = sources.shift();

	if (isObject(target) && isObject(source)) {
		for (const key in source) {
			if (isObject(source[key])) {
				if (!target[key]) Object.assign(target, { [key]: {} });
				mergeDeep(target[key], source[key]);
			} else {
				Object.assign(target, { [key]: source[key] });
			}
		}
	}
	return mergeDeep(target, ...sources);
}

size();
_C.style.setProperty('--n', N);

window.addEventListener('resize', size, false);

_C.addEventListener('mousedown', lock, false);
_C.addEventListener('touchstart', lock, false);

_C.addEventListener('mouseout', move, false);
_C.addEventListener('mouseup', move, false);
_C.addEventListener('touchend', move, false);
</script>
</body>
</html>